我有一个“项目”表和一个“项密钥”表。 当用户搜索关键字时,我想给他一页结果加上结果总数。
我目前正在做的是(对于搜索“a b c”的用户:
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 :(得分: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();
答案 1 :(得分:1)
如果您真的担心性能并且最终需要进行两次查询,则可能需要考虑缓存匹配的总数,因为当用户浏览结果页时,这不会改变。 / p>
答案 2 :(得分:0)
您有两个选择:
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(*)函数不受limit子句的影响。我先用DESCRIBE
对此进行测试。我不知道它会对你的查询速度产生多大影响。只需要给出前10个结果的查询应该比必须查找计数的所有结果的查询短,然后是前10个,但我可能在这里错了。
答案 3 :(得分:0)
您可能会在第一个语句中查看MySQL SQL_CALC_FOUND_ROWS
,然后是第二个语句SELECT FOUND_ROWS()
,这至少会阻止您进行2次数据查询,但仍会倾向于进行一次整个表扫描。< / p>
见http://dev.mysql.com/doc/refman/5.0/en/select.html和 http://dev.mysql.com/doc/refman/5.0/en/information-functions.html
最好考虑一下:你真的需要这个功能吗?