加快查询性能的最佳做法是什么?

时间:2017-03-30 23:52:49

标签: mysql query-performance

我有一个查询,对于连接3个表的100个记录需要80秒,这是非常糟糕的性能,我试图找出快速检索数据的选项? 我将在我的ASP.net Web应用程序中使用此查询并返回带有相应字段的对象。

以下是我能想到的?

1.有更好的方法来编写此查询吗?

2.如果我分开了查询,我怎么能避免使用一个mysql-query-in-a-while-loop-in-php

select distinct spb.software_product_build,spb.date_created,spb.date_announced,ts.suite_name,ssr.MTBF,ssr.CPTH,ssr.TotalProductCrashes,ssr.TotalUniqueCrashes 

from software_product_builds spb 
inner join software_products sp on spb.software_product_id=sp.id     
inner join sp_default_variant spd on   spb.variant_id=spd.default_variant_id       
left join bit_sanity_results bsr on bsr.software_product_build_id=spb.software_product_build_id    
left join test_suites ts on bsr.test_suite_id=ts.id     
left join sns_sanity_results ssr on ssr.software_product_build_id=spb.software_product_build_id     
where sp.software_product='XXXX.LA.0.1' order by spb.software_product_build_id desc limit 100

1 个答案:

答案 0 :(得分:2)

您可能会喜欢我的演示文稿,How to Design Indexes, Reallyvideo of me presenting it

我只能通过阅读您的查询来告诉您可能已经定义了哪些索引,或者表之间的关系是什么。因此,提出正确的建议有点困难。

但是,例如,如果您有一个表spb并且它正在加入表sp,那么对于spb的每一行,它都会执行查找在sp中找到匹配的行。索引位于sp将有助于查找。

from software_product_builds spb 
inner join software_products sp 
  on spb.software_product_id=sp.id
where sp.software_product='XXXX.LA.0.1' 

在这种情况下,您还可以在software_product列上进行常量查找。因此,您可以减少查找到那些匹配行的子集。

ALTER TABLE software_products ADD INDEX (software_product, id);

此索引有助于将搜索范围缩小到该表的一行。 MySQL甚至可能会决定反转连接目录,因为查找sp中的一行然后加入spb中的匹配行可能是最有效的方法。

另一方面,你有ORDER BY spb.software_product_build_id所以MySQL可能更喜欢在该列上使用索引,因此它可以按索引顺序扫描而不是对结果进行排序。除非它首先在连接顺序中访问spb表,否则它无法做到这一点。所以请确保你有一个索引:

ALTER TABLE software_product_builds ADD INDEX (software_product_build_id);

然后让MySQL找出最有效的路径。它经常出人意料地选择最佳选择。

同样对于其他联接,您希望索引将用于查找的列。

ALTER TABLE sp_default_variant ADD INDEX (default_variant_id);
ALTER TABLE bit_sanity_results ADD INDEX (software_product_build_id);
-- ALTER TABLE test_suites ADD INDEX (id);
ALTER TABLE sns_sanity_results ADD INDEX (software_product_build_id);

我为test_suites注释了一个,因为我认为它的id列是主键,并且已经隐式索引了。如果其他情况已经有索引或它们是相应表的主键,则跳过创建新索引。