2008-09-28 37 views
3

我有一个“items”表和一个“itemkeywords”表。 当用户搜索关键字时,我想给他一页结果加上结果总数。在表格中搜索并获得结果和结果数量的最佳方法(MySQL)

我在做什么目前是(针对搜索“ABC”用户:

SELECT DISTINCT {fields I want} FROM itemkeywords JOIN items 
    WHERE (keyword = 'a' or keyword='b' or keyword='c' 
    ORDER BY "my magic criteria" 
    LIMIT 20.10 

,然后我做同样的查询与计数

SELECT COUNT(*) FROM itemkeywords JOIN items 
    WHERE (keyword = 'a' or keyword='b' or keyword='c' 

这可能会得到一个相当大的桌子,我认为这个解决方案非常吸...
但我想不出什么好多了

明显的替代避免打MySQL两次,这是只做第一个查询,没有LIMIT子句,然后导航到正确的记录显示相应的页面,然后到记录集的结尾,以计算结果似乎更糟糕...

任何想法?

注:我使用ASP.Net和MySQL,PHP不

+0

在过去的应用程序中,我使用了两种技术(两个查询和一个没有限制子句的查询),具体取决于我期待的结果数量。我认为有一个想法(虽然我从来没有尝试过)正在加入一个几乎相同的子查询来计算。这将是1分贝命中,但仍然有IO。 – 2008-09-28 16:40:22

回答

5

后选择添加SQL_CALC_FOUND_ROWS在你有限的选择,然后做一个 “SELECT FOUND_ROWS()” 之后的第一选择完成。

例子:

mysql> SELECT SQL_CALC_FOUND_ROWS * FROM tbl_name 
    -> WHERE id > 100 LIMIT 10; 
mysql> SELECT FOUND_ROWS(); 
0

你有2种选择:

MySQL的API应该有一个返回的行数的函数。使用旧的API它的mysql_num_rows()。如果您使用未缓冲的查询,这将不起作用。

的更简单的方法可能是到这两个查询组合:

SELECT DISTINCT {fields I want}, count(*) as results 
     FROM itemkeywords JOIN items 
     WHERE (keyword = 'a' or keyword='b' or keyword='c' 
     ORDER BY "my magic criteria" 
     LIMIT 20.10 

我做了一些测试,和COUNT(*)的功能不会受到限制条款。我会首先用DESCRIBE进行测试。我不知道它会影响你的查询速度。只有前10个结果的查询应该短于那个必须查找所有计数结果,然后是前10个的查询,但我可能在这里是错误的。

1

如果您真的担心性能,并且最终需要进行两个查询,则可能需要考虑缓存匹配的总数,因为用户浏览结果页面时不会发生更改。