0

For the past two days i've been messing about with a single query. I've tried to dissect it's individual parts in a myriad of ways and have discovered the query only breaks when i add in the LEFT OUTER JOINs. I've tried in many different ways to even have one of my reference tables joined to some of the tables I want to use in my actual statement, but thus far to no avail.

(Note; Column selector has been kept to "*" for readability, there's a ton of rows here normally. Behaviour is the same when I test with the * selector.)

My full query:

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;

This database has been transferred from a MS-SQL server, hence i'm rewriting the queries to fit this change. The old query (still) works and used to be as follows:

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; 

Would anyone perhaps have any pointers as to where I might screwing up?

Things i've tried: Removing WHERE-Clauses, adding "AS" keywords (as also done in MSSQL), Attempting a single left outer join and a single inner join on one table.

Edit: It might be worth noting this would be the first time I'm using MySQL instead of MSSQL/T-SQL, I have ofcourse tried to look up other examples, but this hasn't helped me thus far.

Annihlator
  • 204
  • 2
  • 12
  • 1
    have the indexes that existed in sql-server been created on mysql as well? I don't know about sql-server but mysql can only use one index per query so even if you have created the same indexes they might still not work for you. – e4c5 Oct 06 '15 at 14:38
  • Apparently `MySQL` can use multiple indexes per query. Source: http://stackoverflow.com/questions/12222630/can-mysql-use-multiple-indexes-for-a-single-query – Evaldas Buinauskas Oct 06 '15 at 14:45
  • If you have access to SQL Server Management studio, you can use the query optimization tool to create indices and statistics that should help with the execution time of the query. – HashPsi Oct 06 '15 at 15:51
  • @HashPi Thanks, I have and do use SQL Server Management studio, but it's not simply a performance issue. Also, the queries work fine thus far on the MS-SQL side. Also, as far as the performance of working queries goes, that isn't too shabby. Currently it seems MySQL runs into some kind of semi-infinite loop, i've left the query running overnight and still had to manually abort the execution this morning, about 9 hours later... Also, all Joins i'm trying to use here are using the pk's of the referenced tables... don't honestly think it should make a difference in this case... but who knows. – Annihlator Oct 07 '15 at 06:07

2 Answers2

1

Looking at your query, having indexes is one thing, having indexes that are better optimized for what you are asking for is another. Do you have compound indexes ON your tables? I would assume you have indexes on your primary keys that are based on the JOIN components. But three in particular I would index on multiple fields for the index.

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

It appears you "SO_Activity" table has "Activity" as the primary key.

One additional option under MySQL. If these indexes do not help, then I would try adding the keyword "STRAIGHT_JOIN" to tell MySQL to join in the exact order as you have listed the tables as the others are all subject to the primary sales order you are intending which is for the specific customer... which is probably a small set in the scheme of the database content.

SELECT STRAIGHT_JOIN * from ...
DRapp
  • 43,407
  • 11
  • 68
  • 131
  • Thanks for your input! By a compound index you'd mean a single index that target multiple columns I assume? Thus far I have appointed most Indices with a seperate column, save for the columns BeginActivity and EndActivity, they're stored in the same index with a UNIQUE trigger (as the Activity numbers are unique). I just hadn't thought to include the date column on SO_Activity, thanks for that reminder :) And for clarification; Do I understand correctly from your reply that in my current query the tables aren't necessarily joined in the order I list them, but this order may be switched? – Annihlator Oct 07 '15 at 11:57
  • @Annihlator, correct on single index with multiple columns. Correct on order being joined. Sometimes the engine can interpret and SOMETIMES make a less than optimal join. Encountered doing queries against government contract/grants data of 15+ million records and about 20 lookup tables for verbose descriptions of keys. Crashed after 20+ hours. Added STRAIGHT_JOIN and it worked in less than 2 hrs (considering amount of data being pulled, was great timing). – DRapp Oct 07 '15 at 12:41
  • Thanks for the tips, I had always simply assumed tables generally were joined in the order it's scripted. I've changed some of the indices to compound ones and in some cases i have added an additional compound index. Query execution time has gone down from 1.1s when I had only added missing indices, to 0.26s after changing to compound indexes, to 0.16s when some of the removed singular indexes were added back to the tables where I had replaced them with compound ones. Major improvement! – Annihlator Oct 07 '15 at 15:05
0

For some odd reason when I tried running the same queries again without 'AS' mentions in them and only a single Left Outer Join (the one i let execute past night still had them in) after 4.5 sec the query seems to run through and fetching is complete after 10 minutes... once I added a second left outer join the fetching time went up to nearly 16 minutes... Might simply have something to do with the massive amount of data which is actually returned...

This makes me assume the issue lies (no longer, or maybe never really was?) in syntax and after all is a performance issue. I'm familiar to employing SQL Server Management Studio for performance debugging but hadn't employed MySQL Workbench for the same purpose yet... seems like these tools are only supported from MySQL 5.6.6+, since both my production and testserver run MySQL 5.5.44 (These systems run on Debian Jessie) I'll have to figure out a way to do this... will probably end up firing up an additional test-vm for this at the end of today..

I'm confused as to how the performance would deter so much from the implementation we have/had on MS-SQL... Will have to research this in-depth. If anyone passing by happens to have any leads, that'd be tremendously appreciated.

Edit; My sincere apologies, seems like i've simply made some errors while I was recreating my tables and I hadn't made the proper indexes for two of the tables... I feel so stupid. Thanks for the help!

Annihlator
  • 204
  • 2
  • 12