3

我有一个“项目”表和一个“项目关键字”表。当用户搜索关键字时,我想给他一页结果加上结果总数。

我目前正在做的是(对于搜索“ab 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

4

4 回答 4

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();
于 2008-09-28T16:47:00.307 回答
1

如果您真的担心性能并且最终需要进行两次查询,您可能需要考虑缓存匹配的总数,因为这不会随着用户浏览结果页面而改变。

于 2008-11-10T03:43:05.343 回答
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 个。但我在这里可能错了。

于 2008-09-28T16:48:54.873 回答
0

您可能会在第一条语句中查看 MySQL SQL_CALC_FOUND_ROWS,然后是第二条语句SELECT FOUND_ROWS(),这至少可以防止您执行 2 次数据查询,但仍倾向于执行一次整个表扫描。

请参阅http://dev.mysql.com/doc/refman/5.0/en/select.htmlhttp://dev.mysql.com/doc/refman/5.0/en/information-functions.html

最好考虑一下:你真的需要这个功能吗?

于 2008-09-28T16:50:02.530 回答