我有一个包含500k行的2 gb mysql表,我在没有负载的系统上运行以下查询。
select * from mytable
where name in ('n1', 'n2', 'n3', 'n4', ... bunch more... )
order by salary
需要一个文件夹,需要50到70秒才能完成。
按工资删除订单并在应用程序中进行排序时,总运行时间(包括排序)减少到大约25-30秒。但那仍然太过分了。
知道如何加快速度吗?
谢谢。
答案 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)
一些想法:
答案 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
...
我在上面给出的索引可能意味着查询优化器通过索引而不是表扫描来访问行。