AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / dba / 问题 / 253251
Accepted
Michael Cherevko
Michael Cherevko
Asked: 2019-11-15 00:22:55 +0800 CST2019-11-15 00:22:55 +0800 CST 2019-11-15 00:22:55 +0800 CST

使用 group by 和 window 函数减少表扫描

  • 772

我正在尝试改进的代码如下所示(简单示例):

SELECT    DISTINCT a.col_a
         ,COALESCE(b1.col_c, b2.col_c, b3.col_c)
FROM      tab_a a
LEFT JOIN tab_b b1
          ON a.col_a = b1.col_a
             AND b1.col_b = 'blabla1'
LEFT JOIN tab_b b2
          ON a.col_a = b2.col_a
             AND b2.col_b = 'blabla2'
LEFT JOIN tab_b b3
          ON a.col_a = b3.col_a
             AND b3.col_b = 'blabla3';

您可以使用以下脚本重新创建这些表

CREATE TABLE tab_a(col_a int)
CREATE TABLE tab_b(col_a INT, col_b VARCHAR(10), col_c INT)

INSERT INTO dbo.tab_a ( col_a ) VALUES ( 1 ), ( 2 ), ( 3 );

INSERT INTO dbo.tab_b ( col_a
                       ,col_b
                       ,col_c )
VALUES ( 1, 'blabla1', 1 )
      ,( 1, 'blabla2', 3 )
      ,( 1, 'blabla2', 5 )
      ,( 2, 'blabla2', NULL )
      ,( 2, 'blabla3', 5 );

如何将其更改为 1 join + 也许是窗口函数以及如何重写合并部分。只是为了解释一下,当前计划显示 3 个 tab_b 扫描,我想将其减少到 1 个。

sql-server sql-server-2016
  • 3 3 个回答
  • 435 Views

3 个回答

  • Voted
  1. Best Answer
    sepupic
    2019-11-15T03:14:32+08:002019-11-15T03:14:32+08:00
    SELECT    DISTINCT a.col_a
             ,b.col_c
    FROM      tab_a a
    outer apply (select top 1 b.col_c 
                 from tab_b b
                 where ((a.col_a = b.col_a
                         AND b.col_b = 'blabla1' )
                      or (a.col_a = b.col_a
                         AND b.col_b = 'blabla2')
                      or (a.col_a = b.col_a
                         AND b.col_b = 'blabla3'))
                      and b.col_c is not null
                order by b.col_b)b;
    

    此解决方案有 1 个 tab_bscan但添加sort是因为您想b.col_c在COALESCE. 在上面的示例中,这order对应于order您的constantsinjoin condition对应于c列的值。如果顺序应该不同,事情会更复杂,因为你应该编写自定义order by子句。

    • 5
  2. pncsoares
    2019-11-15T00:36:49+08:002019-11-15T00:36:49+08:00

    如果您希望或拥有这 3 个描述静态,您可以执行以下操作:

    1. 创建临时表或变量表
    2. 在临时表或变量表中插入值,但以列的形式 https://stackoverflow.com/questions/15745042/efficiently-convert-rows-to-columns-in-sql-server

    3. 在您的答案中编写脚本,但删除那些 3 LEFT JOIN,然后对临时表或变量表执行 CROSS JOIN

    4. 更改 COALESCE 代码以从 CROSS JOIN 对象中获取值

    您还可以更改数据库模型以满足您最需要的内容。

    为了提供帮助,请分享当前的数据库模型,以便我们进一步帮助您。您可以使用以下选项创建它:

    在此处输入图像描述

    • 1
  3. eagle275
    2019-11-15T01:30:34+08:002019-11-15T01:30:34+08:00
    SELECT    DISTINCT a.col_a
             ,b1.col_c
    FROM      tab_a a
    LEFT JOIN tab_b b1
              ON a.col_a = b1.col_a
                 AND b1.col_b IN ('blabla1','blabla2','blabla3');
    

    1 按要求加入 ^^ 使用 IN (..) 编辑为更优雅的风格

    • 0

相关问题

  • SQL Server - 使用聚集索引时如何存储数据页

  • 我需要为每种类型的查询使用单独的索引,还是一个多列索引可以工作?

  • 什么时候应该使用唯一约束而不是唯一索引?

  • 死锁的主要原因是什么,可以预防吗?

  • 如何确定是否需要或需要索引

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    连接到 PostgreSQL 服务器:致命:主机没有 pg_hba.conf 条目

    • 12 个回答
  • Marko Smith

    如何让sqlplus的输出出现在一行中?

    • 3 个回答
  • Marko Smith

    选择具有最大日期或最晚日期的日期

    • 3 个回答
  • Marko Smith

    如何列出 PostgreSQL 中的所有模式?

    • 4 个回答
  • Marko Smith

    列出指定表的所有列

    • 5 个回答
  • Marko Smith

    如何在不修改我自己的 tnsnames.ora 的情况下使用 sqlplus 连接到位于另一台主机上的 Oracle 数据库

    • 4 个回答
  • Marko Smith

    你如何mysqldump特定的表?

    • 4 个回答
  • Marko Smith

    使用 psql 列出数据库权限

    • 10 个回答
  • Marko Smith

    如何从 PostgreSQL 中的选择查询中将值插入表中?

    • 4 个回答
  • Marko Smith

    如何使用 psql 列出所有数据库和表?

    • 7 个回答
  • Martin Hope
    Jin 连接到 PostgreSQL 服务器:致命:主机没有 pg_hba.conf 条目 2014-12-02 02:54:58 +0800 CST
  • Martin Hope
    Stéphane 如何列出 PostgreSQL 中的所有模式? 2013-04-16 11:19:16 +0800 CST
  • Martin Hope
    Mike Walsh 为什么事务日志不断增长或空间不足? 2012-12-05 18:11:22 +0800 CST
  • Martin Hope
    Stephane Rolland 列出指定表的所有列 2012-08-14 04:44:44 +0800 CST
  • Martin Hope
    haxney MySQL 能否合理地对数十亿行执行查询? 2012-07-03 11:36:13 +0800 CST
  • Martin Hope
    qazwsx 如何监控大型 .sql 文件的导入进度? 2012-05-03 08:54:41 +0800 CST
  • Martin Hope
    markdorison 你如何mysqldump特定的表? 2011-12-17 12:39:37 +0800 CST
  • Martin Hope
    Jonas 如何使用 psql 对 SQL 查询进行计时? 2011-06-04 02:22:54 +0800 CST
  • Martin Hope
    Jonas 如何从 PostgreSQL 中的选择查询中将值插入表中? 2011-05-28 00:33:05 +0800 CST
  • Martin Hope
    Jonas 如何使用 psql 列出所有数据库和表? 2011-02-18 00:45:49 +0800 CST

热门标签

sql-server mysql postgresql sql-server-2014 sql-server-2016 oracle sql-server-2008 database-design query-performance sql-server-2017

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve