如何加速MS Access中无法建索引的左连接SQL查询?
无法创建索引时加速左连接SQL查询的方法
涉及两张表:每日销售数量数据表(dbo_EPOS_Daily_split)、每周库存数量数据表([dbo_C_ Stock]),需求是只要存在每日销售数据就显示两表数据(库存为空也需展示),因此使用左连接。当前执行以下SQL耗时2-3分钟,且无法修改表或创建索引,以下是优化方案:
原查询代码:
SELECT dbo_EPOS_Daily_split.EndDay, dbo_EPOS_Daily_split.Item_Code, dbo_EPOS_Daily_split.SalesUnitsUK, [dbo_C_ Stock].Total_Units, [dbo_C_ Stock].STOCK_DATE FROM dbo_EPOS_Daily_split LEFT JOIN [dbo_C_ Stock] ON (dbo_EPOS_Daily_split.Item_Code = [dbo_C_ Stock].Material) AND (dbo_EPOS_Daily_split.EndDay = [dbo_C_ Stock].STOCK_DATE) WHERE (((dbo_EPOS_Daily_split.EndDay)>=#1/1/2022# And (dbo_EPOS_Daily_split.EndDay)<=#2/1/2022#) AND ((dbo_EPOS_Daily_split.Item_Code)="8830231")) ORDER BY dbo_EPOS_Daily_split.EndDay DESC;
优化建议
- 先过滤销售表再连接:原查询是先对全表做左连接再过滤,改成先筛选出符合条件的销售数据,再和库存表连接,大幅减少连接的数据量:
SELECT filtered.EndDay, filtered.Item_Code, filtered.SalesUnitsUK, stock.Total_Units, stock.STOCK_DATE FROM ( -- 先筛选出目标日期和商品的销售数据 SELECT EndDay, Item_Code, SalesUnitsUK FROM dbo_EPOS_Daily_split WHERE EndDay >= #1/1/2022# AND EndDay <= #2/1/2022# AND Item_Code = "8830231" ) AS filtered LEFT JOIN [dbo_C_ Stock] AS stock ON filtered.Item_Code = stock.Material AND filtered.EndDay = stock.STOCK_DATE ORDER BY filtered.EndDay DESC;
- 限定库存表的扫描范围:因为库存是每周数据,只需要匹配筛选出的销售日期对应的库存行,避免全表扫描库存表:
SELECT filtered.EndDay, filtered.Item_Code, filtered.SalesUnitsUK, stock.Total_Units, stock.STOCK_DATE FROM ( SELECT EndDay, Item_Code, SalesUnitsUK FROM dbo_EPOS_Daily_split WHERE EndDay >= #1/1/2022# AND EndDay <= #2/1/2022# AND Item_Code = "8830231" ) AS filtered LEFT JOIN [dbo_C_ Stock] AS stock ON filtered.Item_Code = stock.Material AND stock.STOCK_DATE IN (SELECT EndDay FROM filtered) ORDER BY filtered.EndDay DESC;
减少排序开销:如果业务可以接受无序结果,直接去掉
ORDER BY;如果必须排序,确保排序的是已经过滤后的小数据集(上面的优化已经实现),避免对全量连接数据排序。查看执行计划定位瓶颈:通过数据库的执行计划工具,确认是否存在全表扫描的低效环节,比如是否可以利用数据库的临时缓存机制,减少重复扫描操作。
内容的提问来源于stack exchange,提问作者SeekingAssistance97
相关产品推荐
相关产品推荐

