【问题标题】:How does Select Distinct work on a Primary Key in SQL?Select Distinct 如何作用于 SQL 中的主键?
【发布时间】:2012-03-07 06:55:07
【问题描述】:

SQL 优化器如何处理主键上的 Select Distinct?例如

员工表 - (EmpId int 主键,EmpName)

select distinct EmpId from Employee.

考虑到 EmpId 已经不同,优化器会拒绝不同的关键字吗?

【问题讨论】:

  • 执行计划是怎么说的?
  • 你用什么来运行查询?真的是主键索引的实现问题
  • 它将忽略 SQL server 中唯一索引上的 DistinctGroup By

标签: sql query-optimization distinct optimization


【解决方案1】:

您的问题没有固定的规则,每个数据库都可以通过自己的方式处理这个问题。您必须查看数据库的查询执行计划。

但我相信诸如 Oracle、MySQL、Postgres 等现代生产型数据库......只是忽略不同的词,而只是迭代索引(而不是表)。

【讨论】:

    【解决方案2】:

    尝试使用和不使用 DISTINCT 关键字并比较执行计划。

    SQL Server 将为两者生成相同的计划。其他 RDBMS 的 YMMV。

    【讨论】:

    • 另外比较 SELECT DISTINCT NonKeyColumn FROM Employee 可能有助于获得洞察力
    【解决方案3】:

    在 Oracle 11g 下尝试过,它们产生了不同的结果。

    select USERID from TPM_USER
    

    生产:

    SELECT STATEMENT    7.0 7   242479  667 2668    7                   ALL_ROWS                                            
    TABLE ACCESS (FULL) 7.0 7   242479  667 2668    1   TPMDBO  TPM_USER    FULL    TABLE   ANALYZED    1                                       
    

    还有:

    select distinct USERID from TPM_USER
    

    生产:

    SELECT STATEMENT    8.0 7   24725738    667 2668    8                   ALL_ROWS                                            
    HASH (UNIQUE)   8.0 7   24725738    667 2668    1           UNIQUE                                                  
    TABLE ACCESS (FULL) 7.0 7   242479  667 2668    1   TPMDBO  TPM_USER    FULL    TABLE   ANALYZED    1                                       
    

    USERIDTPM_USER 的主键,以防不清楚。

    更新:

    Oracle 会这么愚蠢让我有些恼火,因此我在我们的生产服务器上尝试了相同的查询,该服务器拥有大约一千倍的数据。这一次,两个查询计划是相同的(两次都使用了索引,没有进行全表扫描)。这让我相信规划器在决定走哪条路线时会考虑表格统计信息。

    生产(有或没有DISTINCT):

    SELECT STATEMENT    3.0 3   461492  3521    14084   3                   ALL_ROWS                                            
    INDEX (FAST FULL SCAN)  3.0 3   461492  3521    14084   1   TPMDBO  TPM_USER_PK FAST FULL SCAN  INDEX (UNIQUE)  ANALYZED                                            
    

    【讨论】:

    • 没错,Oracle 会根据统计数据更改执行计划,这就是为什么最好收集统计数据 对您的表(特别是那些有大量插入、更新和删除的表)每隔一段时间。
    【解决方案4】:

    SQL Server 不会为我生成相同的计划。

    在非索引列上使用 distinct 进行查询会使用哈希匹配,而在主键上查询则不会这样做。

    【讨论】:

    • 也就是说,在 pk 和非 pk 列之间不会产生相同的结果。当然,无论您是否在 pk 上使用 DISTINCT,它都会产生相同的结果。
    【解决方案5】:

    我不确定您所说的拒绝是什么意思,但鉴于根据定义,主键是非 NULL 且唯一的,我确信排序/分组操作被忽略,因为对于生成执行而言是不必要的在大多数 RDBMS 系统中进行规划。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-07-11
      • 2015-06-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-05-10
      • 1970-01-01
      相关资源
      最近更新 更多