我注意到在查询结尾添加LIMIT 1
不会减少执行时间。我有几千条记录和一个简单的查询。如何在第一场比赛后让MySQL停止?
例如,这两个查询都需要大约半秒钟:
SELECT id,content FROM links WHERE LENGTH(content)<500 ORDER BY likes
SELECT id,content FROM links WHERE LENGTH(content)<500 ORDER BY likes LIMIT 1
编辑:以下是解释结果:
id | select_type | table | type possible_keys | key | key_len | ref | rows | Extra
1 | SIMPLE | links | ALL | NULL | NULL | NULL | NULL | 38556 | Using where; Using filesort
答案 0 :(得分:1)
两个查询运行时间之间的差异取决于实际数据。
有几种可能的情况:
LENGTH(content)<500
在这种情况下,MySQL将开始扫描所有表行(根据主键顺序,因为您没有提供任何ORDER BY)。
没有索引使用,因为您的WHERE条件无法编入索引。
由于LENGTH(content)<500
行的行数相对较多,因此LIMIT查询的返回速度将快于另一行。
没有LENGTH(content)<500
的记录
同样,MySQL将开始扫描所有表行,但必须通过所有记录来确定它们都不满足条件。
同样,由于同样的原因,不能使用索引。
在这种情况下 - 两个查询将具有完全相同的运行时。
这两种情况之间的任何内容都会有不同的运行时间,因为表中有更多有效记录,所以运行时间会更远。
修改强> 现在您添加了ORDER BY,答案有点不同:
如果在likes列上有索引,ORDER BY会使用它,时间将是到达满足WHERE条件的第一条记录所需的时间(如果有66%的记录,则比这应该比没有LIMIT更快。
如果在likes列上没有索引,则ORDER BY将占用大部分时间--MySQL必须扫描所有表以获取满足WHERE的所有记录,然后按喜欢排序,然后取第一个一。 在这种情况下,两个查询都将具有相似的运行时间(扫描和排序结果比返回1条记录或许多记录要长得多......)
答案 1 :(得分:0)
对数据调用函数会导致自动表扫描,这些不能被索引。你可能会做的是创建一个派生列,如果性能是一个问题,你提前保存了这个值:
ALTER TABLE links ADD COLUMN content_length INT
UPDATE links SET content_length=LENGTH(content)
ALTER TABLE links ADD INDEX idx_content_length (content_length)
一旦这样非规范化,你就可以更快地运行查询。请注意,每次添加记录时都必须填充content_length
。