我的查询非常慢,因为使用了ORDER BY。现在我理解为什么它很慢但我不知道如何让它更快。
该表得到了900.000条记录。 (原因很慢)
SELECT SQL_NO_CACHE id, name
FROM users where is_provider = 0
AND activated_at IS NOT NULL
AND is_ngo = 0
AND deleted_at is NULL
AND is_cancelled = 0
ORDER BY name
LIMIT 60000, 90;
我使用限制因为我使用分页。 SQL_NO_CACHE因为我不想使用缓存进行测试。
此查询需要60秒,这太长了。这是一个后台任务,所以如果我能在5秒内减少它就可以了
我在activated_at列和deleted_at上有索引,它们是时间字段。其他的是布尔值,所以不需要索引。
由于
答案 0 :(得分:3)
我认为索引是答案,但你必须弄清楚你的查询的正确索引,所以你应该试试这个:
EXPLAIN SELECT SQL_NO_CACHE id, name
FROM users where is_provider = 0
AND activated_at IS NOT NULL
AND is_ngo = 0
AND deleted_at is NULL
AND is_cancelled = 0
ORDER BY name
LIMIT 60000, 90;
在这篇非常古老但有用的文章中详细说明:
http://www.databasejournal.com/features/mysql/article.php/1382791/Optimizing-MySQL-Queries-and-Indexes.htm
答案 1 :(得分:2)
您可能会发现此文章有用:http://www.mysqlperformanceblog.com/2006/09/01/order-by-limit-performance-optimization/
它涉及ORDER BY和LIMIT的组合。
答案 2 :(得分:1)
我猜这是按名称排序使它变慢。
要测试,请删除ORDER子句并检查所需的时间。
当您想要按名称命名时,名称字段可能应编入索引。
答案 3 :(得分:1)
我建议在最具选择性的布尔字段上添加索引,即,如果数据库中只有5%的行有is_provider = 0
,那么您可以显着减少扫描所需的行数对于其他属性。如果分布是50/50那么没什么意义,但我会查看分布,并指导您确定哪些索引可能有用。当然,您应该以实际表现为指导(包括您可能拥有的其他查询)。
答案 4 :(得分:0)
或者,删除Order By子句并在阅读完记录后执行订购。它将工作放在客户端上,但如果数据库速度很慢(如此处所示),则可能更可靠,更快。
干杯,
丹尼尔
答案 5 :(得分:0)
名称列是否已作为另一个索引的一部分编入索引?
索引排序应该相对较快(不需要filesort),除非name恰好是索引的一部分,而不是第一部分。 点击此处:http://dev.mysql.com/doc/refman/5.0/en/order-by-optimization.html
请发布您的EXPLAIN
结果,以便我们进一步提供帮助......
答案 6 :(得分:0)
你可以尝试
SELECT * FROM (SELECT SQL_NO_CACHE id, name
FROM users where is_provider = 0
AND activated_at IS NOT NULL
AND is_ngo = 0
AND deleted_at is NULL
AND is_cancelled = 0
ORDER BY name) t
LIMIT 60000, 90;
避免ORDER BY和LIMIT在一起。
答案 7 :(得分:0)
这里的问题是,Mysql
首先尝试Order By
来Name
表中所有可用行,然后尝试以Where
为条件选择记录。因此,您可以尝试的是首先根据Select
条件创建记录Where
,然后对结果集运行Order By name
。
示例:
SELECT * FROM (SELECT SQL_NO_CACHE id, name
FROM users where is_provider = 0
AND activated_at IS NOT NULL
AND is_ngo = 0
AND deleted_at is NULL
AND is_cancelled = 0) t ORDER BY name
LIMIT 60000, 90;