2012-09-11 165 views
-1

我需要做一个查询,从各个表中获取列 - 总共5个表。我很高兴获得左连接的要点,并获得我需要的结果,唯一的问题是速度。我在索引/键上输了一些,可能是因为我的例子对于我在网上阅读的所有例子都不是很典型。我的表中的“唯一”ID不是所有表中的主键,因为该表可能有多行(历史/审计目的)。 id在多个表格(##/###和## - ###)中也有不同的格式,所以匹配它们的函数可能会导致大幅减速。到目前为止,粘贴我的代码可能会更容易(只有3个表格 - 直到我可以先征服3个表格才能完成所有这些工作!),并且有人可以建议如何使用索引和键进行改进。MySQL优化三元左连接

SELECT dc.URN,dc.GuideName,dc.GuideStreet,ss.categorycalc,pm.initiatedate 
FROM dc 
LEFT JOIN pm 
ON dc.URN = pm.URN 
LEFT JOIN ss 
ON dc.URN = replace(ss.URN,"/","-") 
WHERE dc.GuidePCode LIKE 'WA9%' 
ORDER BY pm.Status ASC; 

我将不胜感激更少的意见,刚开始的数据库一切都结束了“做正确”等等 - 有很多的已经编码中插入数据在某些方面某些表程序。因此,改变唯一ID的结构以及将它写入某些表的方式是不切实际的。我只需要关注这个我已经掌握的数据报告。 “WA9”部分将根据用户想要搜索的内容而改变。

+1

该查询的[查询执行计划](http://dev.mysql.com/doc/refman/5.5/en/execution-plan-information.html)是什么?从那里开始或发布结果并显示每个表的“CREATE TABLE”语法和索引。问题中没有足够的信息继续。 – drew010

回答

2

首先我会做一个解释。检查MySQL手册的正确用法,但它基本上是:

EXPLAIN SELECT dc.URN,dc.GuideName,dc.GuideStreet,ss.categorycalc,pm.initiatedate 
FROM dc 
LEFT JOIN pm ON dc.URN = pm.URN 
LEFT JOIN ss ON dc.URN = replace(ss.URN,"/","-") 
WHERE dc.GuidePCode LIKE 'WA9%' 
ORDER BY pm.Status ASC; 

看看“key”列。如果表格的某一行为空,那么您可能需要在这些字段上使用索引。我建议你添加下面的,如果你不已经拥有了它:
(顺便说一句,在测试环境中运行的第一本)

ALTER TABLE dc ADD INDEX URNIdx (URN); 
ALTER TABLE pm ADD INDEX URNIdx (URN); 
ALTER TABLE dc ADD INDEX GuidePCodeIdx (GuidePCode); 

我要说尝试添加索引表SS,但我认为最好创建一个名为URNdashed的新列,并使用与URN相同的定义。然后运行这个UPDATE:

UPDATE ss SET URNdashed = replace(ss.URN, "/", "-"); 

也会增加一个索引URNdashed:

ALTER TABLE ss ADD INDEX URNdashedIdx (URNdashed); 

之后又改变了:

ON dc.URN = replace(ss.URN,"/","-") 
to 
ON dc.URN = URNdashed 

看看是否有帮助。我希望我能朝着正确的方向扼杀你!

+0

非常棒的第一篇文章! – AllInOne

+0

谢谢我会试一试。我已经发现ss表是myisam,其余的都是innodb,我猜测这是一个因素。我该如何设置一个触发器,以便每次插入一个新行时,它会将## - ###版本的瓮复制到新列中?建立一个新的innodb表只适用于urns和category calc – pedromillers

+0

不同的表类型不应该是JOINs的问题....只要EXPLAIN显示索引正在使用,你应该没问题。我一直都在做。它们可能必须是相同的类型和长度,所以如果一个被定义为_TINYINT(1)_,另一个也应该是。确保如果你减少了长度,你不是截断列,所以做一个'SELECT MAX(LENGTH(pm.URN))FROM pm'我没有时间来解释触发器,但是除了在您的应用程序中执行它之外,它还是一种可能的解决方案我建议谷歌搜索MySQL现在触发示例**。 – Carlos