如何优化这个MySQL慢(非常慢)的查询?

时间:2009-08-02 23:19:51

标签: mysql optimization

我有一个包含500k行的2 gb mysql表,我在没有负载的系统上运行以下查询。

select * from mytable 
where name in ('n1', 'n2', 'n3', 'n4', ... bunch more... ) 
order by salary

需要一个文件夹,需要50到70秒才能完成。

按工资删除订单并在应用程序中进行排序时,总运行时间(包括排序)减少到大约25-30秒。但那仍然太过分了。

知道如何加快速度吗?

谢谢。

5 个答案:

答案 0 :(得分:5)

将名称列表放入临时表中,然后在两个表上执行内部联接。这种方法比为每行梳理整个列表要快得多。这是伪代码:

create temporary table names
    (name varchar(255));

insert into names values ('n1'),('n2'),...,('nn');

select
    a.*
from
    mytable a
    inner join names b on
        a.name = b.name

另请注意,name应该有一个索引。这使事情变得更快 。感谢Thomas发表此笔记。

答案 1 :(得分:1)

一些想法:

  • 你需要选择*,你能否只选择一个子集?
  • 如果你可以选择一个子集,你可以添加一个已经按工资排序的覆盖索引
  • 如果一切都有相同的模式,你可以做LIKE('n%')

答案 2 :(得分:1)

尝试使用子查询选择所需的行,然后对该子查询的结果进行排序。 See this question

你在name的{​​{1}}上有一个索引,对吗?

答案 3 :(得分:1)

根据数据分布和WHERE子句匹配的行数,您可能想要尝试(薪水,名称)甚至(名称,工资)的索引虽然后者很可能对这类查询不太有用。

您可能还想增加sort_buffer_size设置。单独测试所有内容并比较EXPLAIN的输出。

答案 4 :(得分:0)

create index xyz on mytable(name(6));

“IN”查询几乎总是效率低下,因为它们在概念上是这样处理的:

select * from mytable where name = n1  
or name = n2
or name = n3
...

我在上面给出的索引可能意味着查询优化器通过索引而不是表扫描来访问行。