我有一个查询,对于连接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
答案 0 :(得分:2)
您可能会喜欢我的演示文稿,How to Design Indexes, Really或video 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
列是主键,并且已经隐式索引了。如果其他情况已经有索引或它们是相应表的主键,则跳过创建新索引。