SQL左联接-在较小的表上速度变慢?

时间:2018-10-25 15:55:57

标签: sql sql-server performance left-join sql-server-express

使用SQL Server Express。我有一个销售交易主表,该表保留了所有销售交易数据的历史记录。该表每天更新,以添加新行来捕获对销售交易的任何更改。

在此表中,我创建了两个视图-一个用于Sales_Closed,一个用于Open_Bookings。每个视图都返回完全相同的列集,仅分别过滤数据。

当我select *中的每一个发生以下情况时:

  • Bookings_open-运行1秒钟,返回〜28,000行。
  • Sales_Closed-运行4秒钟,返回〜200,000行。

此外-我创建了一个表格来捕获最终输出所需的所有相关数据组合,该报告显示了一年前和一年后的未完成预订和未完成销售。该表中标题为Work_Template_month的列是:UPC,位置,渠道,销售类型,月,年和会计年度。

从此表运行Select *会返回:

  • Work_Template_month-运行时间为23秒-1,995,552行(哇,是的,它的确需要这么大,因为我所做的工作比SQL后面的部分所描述的还要多)

所以现在很有趣:如果我在这里运行此SQL查询,然后互换(第14行)

LEFT OUTER JOIN dbo.bookings_open AS E  

LEFT OUTER JOIN dbo.sales_closed AS E

Sales_Closed在23秒内运行

Bookings_open 3:00 !!!!

中运行

为什么较小的桌子要花8倍的时间?!

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

执行计划: Open_Bookingsopen_bookings_execution_plan

Sales_Closedsales_closed_execution_plan

2 个答案:

答案 0 :(得分:0)

您的加入标准是问题

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

如果联接位于外键机智的主键上,则更好,而不是在几个字段上进行查询,这就是为什么执行程序中具有哈希查找的原因。 尝试将覆盖索引添加到sales_type,Channel_month_year和adj_location

答案 1 :(得分:0)

我最终使用gremlin> graph = TinkerGraph.open() gremlin> g = graph.traversal().withRemote(new DriverRemoteConnection('ws://localhost:8182/gremlin')) 的视图制作了一个表(包含确切的列),现在称为Open_Bookings

我将第14行替换为: Open_bookings_tbl

现在它运行了19秒,我仍然感到困惑,高兴但感到困惑。执行计划如下。

Bookings_table_Execution_Plan