简体   繁体   中英

SQL left join- slowing on smaller table?

Using SQL Server Express. I have a master table of sales transactions that keeps the history of all sales transaction data. This table updates daily to add a new line capturing any changes to the sales transaction.

From this table, I have two views created - one for Sales_Closed and one for Open_Bookings . Each view returns the exact same column set, only the data is filtered respectively.

When I select * from each, the following occurs:

  • Bookings_open - runs in 1 second, returns ~28,000 rows.
  • Sales_Closed - runs in 4 seconds , returns ~200,000 rows.

Additionally- I have created a table to capture all combinations of relevant data needed for my final output, a report showing open bookings and closed sales 1 year back and 1 year forward. The columns from this table titled Work_Template_month are: UPC, Location, Channel, sales type, Month, Year and fiscal year.

Running Select * from this table returns:

  • Work_Template_month - runs in 23 seconds- 1,995,552 rows (wowzers, and yes it does need to be this big because I am doing more than described in later parts of the SQL)

So now the fun: if I run this SQL query here, and interchange (line 14)

LEFT OUTER JOIN dbo.bookings_open AS E  

with

LEFT OUTER JOIN dbo.sales_closed AS E

Sales_Closed runs in 23 seconds

Bookings_open runs in 3:00 !!!!

Why would the smaller table take 8 times as long?!

SELECT       
    D.upc, 
    D.sales_type, 
    D.channel, 
    D.month, D.year, D.fiscal_year,
    D.adj_location,
    SUM(E.qty_sold) AS Sales_Qty, 
    SUM(CAST(E.total_adjust_dollars AS money)) AS Sales_Dollars
FROM            
    dbo.work_template_month AS D 
LEFT OUTER JOIN 
    dbo.bookings_open AS E ON D.upc = E.upc 
                           AND D.sales_type = E.sales_type 
                           AND D.channel = E.channel_name 
                           AND D.month = E.shipped_month 
                           AND D.year = E.shipped_year 
                           AND D.adj_location = E.adj_location
GROUP BY 
    D.upc, D.sales_type, D.channel, 
    D.month, D.year, D.fiscal_year,
    D.adj_location

Execution plan: Open_Bookings : open_bookings_execution_plan

Sales_Closed : sales_closed_execution_plan

Your join criteria is the problem

ON D.upc = E.upc 
                           AND D.sales_type = E.sales_type 
                           AND D.channel = E.channel_name 
                           AND D.month = E.shipped_month 
                           AND D.year = E.shipped_year 
                           AND D.adj_location = E.adj_location

IF the join was on a Primary Key to a foreign key wit would be better instead you are querying on several fields thats why the executuin has a hashed lookup in it. Try adding covering indexes to the sales_type,Channel_month_year, and adj_location

I ended up using the view for Open_Bookings to make a table (with the exact columns) now called Open_bookings_tbl .

I replaced line 14 with: LEFT OUTER JOIN dbo.bookings_open_tbl AS E

This now runs in 19 seconds and I am still perplexed, happy but perplexed. Execution Plan below.

Bookings_table_Execution_Plan

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM