2015-10-06 45 views
0

过去两天我一直在搞单个查询。 我试图解剖它的各个方面的个别部分,并发现查询只有当我添加在左外部联接中断。 我试过很多不同的方法,甚至有我的参考表加入到我想在我的实际声明中使用的一些表中,但迄今无济于事。MySQL - 无尽的查询左外部联接

(注;列选择一直保持在“*”的可读性,有一吨的行这里通常的行为是一样的,当我与*选择测试。)

我的完整的查询:

SELECT * 
     FROM SO_SalesOrder so 
     INNER JOIN SO_Leg as l ON l.SalesOrder = so.SalesOrdernr 
     INNER JOIN SO_Cargo cg ON cg.Cargonr = l.Cargo 
     INNER JOIN SO_Activity ea ON ea.Activitynr = l.EndActivity 
     INNER JOIN SO_Activity ba ON ba.Activitynr = l.BeginActivity 
     LEFT OUTER JOIN RP_TripActivity eta ON eta.Activity = l.EndActivity 
     LEFT OUTER JOIN Product p ON p.Productnr = cg.Product 
     WHERE ba.Date BETWEEN '2015-10-01 00:00:00' AND '2015-10-07 23:59:59' 
     AND OrderStatus != 2 
     AND so.Customer = 95; 

此数据库已从MS-SQL服务器传输,因此我正在重写查询以适应此更改。 旧查询(仍然)的作品,并用于如下:

SELECT * 
    FROM dbo.SO_SalesOrder as so 
    INNER JOIN dbo.SO_Leg as l ON l.SalesOrder = so.SalesOrdernr 
    INNER JOIN dbo.SO_Cargo AS cg ON cg.Cargonr = l.Cargo 
    INNER JOIN dbo.SO_Activity AS ea ON ea.Activitynr = l.EndActivity 
    INNER JOIN dbo.SO_Activity AS ba ON ba.Activitynr = l.BeginActivity 
    LEFT OUTER JOIN dbo.RP_TripActivity AS eta ON eta.Activity = l.EndActivity 
    LEFT OUTER JOIN dbo.RP_Trip AS et ON et.Tripnr = eta.Trip 
    LEFT OUTER JOIN dbo.RP_ResourceCombination AS erc ON erc.ResourceCombinationnr = eta.ResourceCombination 
    LEFT OUTER JOIN dbo.RP_Resource AS er1 ON er1.Resourcenr = erc.Truck 
    LEFT OUTER JOIN dbo.RP_ResourceCompany AS erc1 ON erc1.Resource = er1.Resourcenr AND erc1.Company = et.Company 
    LEFT OUTER JOIN dbo.VM_Vehicle AS ev1 ON ev1.Vehiclenr = er1.Vehicle 
    LEFT OUTER JOIN dbo.RP_Resource AS er3 ON er3.Resourcenr = erc.Driver 
    LEFT OUTER JOIN dbo.HR_Employee AS eemp3 ON eemp3.Employeenr = er3.Employee 
    LEFT OUTER JOIN dbo.Product AS p ON p.Productnr = cg.Product 
    WHERE ba.Date BETWEEN '2015-10-01 00:00:00' 
    AND '2015-10-07 23:59:59' 
    AND OrderStatus != 2 
    AND so.Customer = 95; 

会有人也许有任何指针作为的地方,我可能会搞砸了?

我试过的东西: 删除WHERE子句,添加“AS”关键字(也在MSSQL中完成),试图在一个表上尝试一个左外连接和一个内连接。

编辑:可能值得注意的是,这将是我第一次使用MySQL而不是MSSQL/T-SQL,我当然试图查找其他示例,但迄今为止这并没有帮助我。

+1

是否已经在mysql上创建了sql-server中存在的索引?我不知道sql-server,但是mysql只能为每个查询使用一个索引,所以即使你创建了相同的索引,它们可能仍然不适合你。 – e4c5

+0

显然'MySQL'可以为每个查询使用多个索引。来源:http://stackoverflow.com/questions/12222630/can-mysql-use-multiple-indexes-for-a-single-query –

+0

如果你有权访问SQL Server Management Studio,你可以使用查询优化工具创建应该有助于查询执行时间的索引和统计信息。 – HashPsi

回答

1

看看你的查询,有索引是一回事,索引是针对你要求的更好的优化是另一回事。你的桌子上有复合索引吗?我假设你有基于JOIN组件的主键上的索引。但是,我特别要指出三个索引的多个字段。

table   index 
SO_SalesOrder (customer, orderstatus, salesordernr) 
SO_LEG   (salesorder, beginactivity, endactivity, cargo) 
SO_Activity  (activitynr, date) 

看起来你“SO_Activity”表中有“Activity”作为主键。

MySQL下的一个附加选项。如果这些索引不起作用,那么我会尝试添加关键字“STRAIGHT_JOIN”,告诉MySQL按照您列出的表格的顺序加入,因为其他人都受您希望的主要销售订单的支配特定的客户......这可能是数据库内容方案中的一个小集合。

SELECT STRAIGHT_JOIN * from ... 
+0

感谢您的输入!通过一个复合索引,你意味着一个单一的索引,目标是我假设的多个列? 迄今为止,我已经指定了大多数具有独立列的索引,除了BeginActivity和EndActivity这两列,它们与UNIQUE触发器(因为活动编号是唯一的)存储在同一个索引中。 我刚刚没有想过在SO_Activity上包含日期列,谢谢你的提醒:) 并澄清; 我是否正确理解您的回复,在我当前的查询中,表格不一定按照我列出的顺序加入,但是此顺序可能会切换? – Annihlator

+0

@Annihlator,更正多个列的单个索引。正确加入订单。有时候引擎可以解释并且有时候会做出不太理想的加入。遇到针对政府合同的查询/授予超过1,500万条记录的数据和约20个查找表以获取密钥的详细描述。 20小时后坠毁。增加了STRAIGHT_JOIN,它在不到2小时的时间内工作(考虑到数据量被拉大,时机很好)。 – DRapp

+0

感谢提示,我总是简单地假定表格通常是按照它的脚本顺序连接的。我已经改变了一些指数来复合一些指数,并且在某些情况下,我已经添加了一个额外的复合指数。查询执行时间从我刚刚添加缺失索引时的1.1秒,到更改为复合索引后的0.26秒,降低到当删除的奇异索引添加回表中已替换为复合索引的表时的0.16秒时。主要改进! – Annihlator

0

由于某些奇怪的原因,当我试图在没有'AS'的情况下再次运行同样的查询时,4.5秒之后只有一个左外部联接(我让过夜执行仍然有一个) 10分钟后完成抓取完成...一旦我添加了第二个左外部连接,抓取时间增加了近16分钟...可能只是与大量数据实际返回有关。

这使得我认为问题在于语法上的问题(不再是,或者可能从来没有真正?),毕竟是性能问题。我熟悉使用SQL Server Management Studio进行性能调试,但并未将MySQL Workbench用于同一目的......似乎这些工具仅支持MySQL 5.6.6+,因为我的生产环境和测试服务器都运行MySQL 5.5.44(这些系统在Debian Jessie上运行)我必须找出一种方法来做到这一点...可能最终会在今天结束时为此启动一个额外的测试-vm ..

我对于性能如何阻碍我们对MS-SQL的执行情况感到困惑......我们必须深入研究这一点。 如果任何路过的人碰巧有任何潜在客户,那会非常感激。

编辑;我诚挚的道歉,好像我只是在重新创建我的表格时犯了一些错误,而且我没有为两个表格创建合适的索引......我感到非常愚蠢。 感谢您的帮助!