如果使用ORDER BY String Column,MySQL查询需要很长时间才能执行

时间:2014-10-09 21:31:02

标签: mysql sql-order-by query-optimization

因此,如果我不使用4 million,我对包含order by条记录的表的查询会立即执行。但是,我想让我的客户按Name字段对结果进行排序,并仅显示过滤结果的最后100。只要我添加order by Name,就需要100秒才能执行。

我的表结构类似于:

CREATE TABLE Test(
   ID INT PRIMARY KEY AUTO_INCREMENT,
   Name VARCHAR(100),
   StatusID INT,
   KEY (StatusID), <-- Index on StatusID
   KEY (StatusID, Name) <-- Index on StatusID, Name
   KEY(Name) <-- Index on Name
);

我的查询只是做了类似的事情:

explain SELECT ID, StatusID, Name
FROM Test
WHERE StatusID = 113
ORDER BY Name DESC
LIMIT 0, 100

以上解释当我按Name订购时给出了这个结果:

enter image description here

StatusID_2StatausID, Name

的综合索引

现在,如果我将ORDER BY Name DESC更改为ORDER BY ID,我会得到: enter image description here

如何在使用100时检查ORDER BY Name行?

3 个答案:

答案 0 :(得分:0)

你可以尝试一件事,尝试在结果中预期100行的字母,如

SELECT *
FROM Test
*** Some Joins to filter data or get more columns from other tables
WHERE StatusID = 12 AND NAME REGEXP '^[A-H]'
ORDER BY Name DESC
LIMIT 0, 100

此外,使用索引对名称非常重要(已经应用) - 在这种情况下,索引范围扫描将在所需的行数生成后立即启动并停止查询。

因此我们无法使用ID,因为当它达到极限时它不会扫描,我们唯一可以尝试的是移除预期结果中不可能的字母,这就是我们要做的事情与REGEXP

答案 1 :(得分:0)

没有连接和解释结果很难分辨,但你并没有明显地使用索引。

可能是因为连接或者因为你在where子句中有另一个键。我建议阅读本文,它涵盖了所有可能的情况:http://dev.mysql.com/doc/refman/5.7/en/order-by-optimization.html

增加sort_buffer_size和/或read_rnd_buffer_size可能会有所帮助......

答案 2 :(得分:0)

您需要一个基于过滤的复合键WHERE标准加上订单...在

上创建一个索引

(StatusID,Name)

这样,WHERE跳转到您的StatusID = 12记录并忽略其余的400万...然后使用该名称作为次要来限定ORDER BY。

如果没有看到其他表/连接条件和关联索引,您可能还想尝试添加MySQL关键字

SELECT STRAIGHT_JOIN ...查询的其余部分

所以它按照您选择的顺序进行查询,但如果没有看到其他联接,则不确定影响。

附加(根据反馈)

我会删除ID上的各个索引,这样引擎就不必猜测要使用哪一个。无论名称如何,复合索引都可以用作仅ID查询,因此您不需要同时使用这两者。

此外,删除Name only index除非您将在名称上查询PRIMARILY作为没有ID限定符的where限定符...此外,您要查询的示例ID甚至可以记录多少总记录数。 400万...你可能想把id的全套作为一个子查询拉出来,得到几千个并按名称排序,这很快......就像... ...

select *
   from ( SELECT 
                ID, 
                StatusID, 
                Name
             FROM 
                Test
             WHERE 
                StatusID = 113 ) PreQuery
   ORDER BY 
      Name DESC
   LIMIT 0, 100