查询是
SELECT row
FROM `table`
USE INDEX(`indexName`)
WHERE row1 = '0'
AND row2 = '0'
AND row3 >= row4
AND (row5 = '0' OR row5 LIKE 'value')
我有以下 MySQL 查询,我已经创建了一个索引供使用;
CREATE INDEX indexName ON `table` (row1, row2, row3, row5);
但是,性能并不是很好。它可以在 6 到 12 秒内从超过 590 万行的表中提取约 17,000 多行。
瓶颈似乎是 row3
>= row4
- 因为代码中没有这一部分,它的运行时间为 0.6-0.7 秒。
(来自评论)
行(占位符列名)实际上是表中的id(主键,索引)列,这就是我稍后输出的结果集。我输出与查询中的参数匹配的 ID 数组,然后从该数组中选择一个随机 ID,以通过特定行的最终查询收集数据。这是作为 rand() 的解决方法完成的。根据这些知识需要进行任何调整吗?
最佳答案
17K 行并不是一个很小的结果集。大型结果集通常需要时间,只是因为将数据从 MySQL 服务器传送到请求它们的程序的开销。
您在 row5 LIKE 'value'
中使用的'value'
内容对于查询性能非常重要。如果 'value'
以通配符(如 %
)开头,您的查询将会很慢。
话虽如此,您需要一个所谓的 covering index 。您已尝试使用您创建的索引创建一个。它很接近,但并不完美。
您的查询会根据 row1
、row2
和 row5
上的常量值进行相等性过滤,因此这些列应位于索引的首位。查询规划器可以随机访问索引到第一个匹配条目,然后顺序扫描索引,直到到达最后一个匹配条目。这已经是最快的了。
然后您想要检查 row3
和 row4
(以比较它们)。这些列应该位于索引中的下一个。最后,如果查询的 SELECT 子句提到了表中列的子集,则应该将其余列放入索引中。因此,根据您问题中的查询,您的索引应该是
CREATE INDEX indexName ON `table` (row1, row2, row5, row3, row4, row);
查询规划器将能够通过使用所谓的索引范围扫描扫描索引的子集来满足整个查询。这应该相当快。
专业提示:不要用 USE INDEX()
强制查询规划者进行操作。相反,构建索引以有效地处理查询。
关于mysql - 由于特定部分而导致 MySQL 索引出现问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46910978/