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 / 问题 / 35082
Accepted
Jānis
Jānis
Asked: 2013-02-21 01:07:29 +0800 CST2013-02-21 01:07:29 +0800 CST 2013-02-21 01:07:29 +0800 CST

SQL Server 中的“No Join Predicate”到底是什么意思?

  • 772

MSDN“缺少连接谓词事件类”说它“表示正在执行一个没有连接谓词的查询”。

但不幸的是,这似乎并不那么容易。

比如很简单的情况:

create table #temp1(i int);
create table #temp2(i int);
Select * from #temp1, #temp2 option (recompile);

表中没有数据,也没有警告,尽管它显然没有连接谓词。

如果我看一下 SQL Server 2005 的文档(相同的链接,只是其他服务器版本),有一个额外的句子:“只有当连接的双方返回多行时才会产生这个事件。 ”这将使在以前的情况下完美的感觉。没有数据,所以双方都返回0行并且没有警告。插入行,得到警告。嗯不错。

但是对于下一个令人困惑的情况,我在两个表中插入了相同的值:

Insert into #temp1 (i) values (1)
Insert into #temp1 (i) values (1)
Insert into #temp2 (i) values (1)
Insert into #temp2 (i) values (1)

我得到:

-- no warning:
Select * from #temp1 t1 
    inner join #temp2 t2 on t1.i = t2.i 
option (recompile)
-- has warning:
Select * from #temp1 t1 
    inner join (select 1 i union all select 1) t2 on t1.i = t2.i 
option (recompile)

为什么会这样?

注意:我用来在我的服务器上检测这些错误查询的一些脚本。

  1. 当然,程序的执行计划
  2. 使用默认服务器跟踪来查找警告

    Declare @trace nvarchar(500);
    Select @trace = cast(value as nvarchar(500))
    From sys.fn_trace_getinfo(Null)
    Where traceid = 1 and property = 2;
    
    Select t.StartTime, te.name, *
    From sys.fn_trace_gettable(@trace, 1) t
        Inner join sys.trace_events te on t.EventClass = te.trace_event_id
        where EventClass = 80
    order by t.StartTime desc
    
  3. 执行计划缓存,找到那些带有警告的计划(比如这个)

    WITH XMLNAMESPACES (default 'http://schemas.microsoft.com/sqlserver/2004/07/showplan')
    SELECT
        Cast('<?SQL ' + st.text + ' ?>' as xml) sql_text,
        pl.query_plan,
        ps.execution_count,
        ps.last_execution_time,
        ps.last_elapsed_time,
        ps.last_logical_reads,
        ps.last_logical_writes
    FROM sys.dm_exec_query_stats ps with (NOLOCK)
        Cross Apply sys.dm_exec_sql_text(ps.sql_handle) st
        Cross Apply sys.dm_exec_query_plan(ps.plan_handle) pl
    WHERE pl.query_plan.value('(//Warnings/@NoJoinPredicate)[1]', 'bit') = 1
    Order By last_execution_time desc
    OPTION (RECOMPILE);
    
sql-server-2008 sql-server-2005
  • 1 1 个回答
  • 34582 Views

1 个回答

  • Voted
  1. Best Answer
    Martin Smith
    2013-02-21T02:43:20+08:002013-02-21T02:43:20+08:00

    您的问题与此类似。有时 SQL Server 可以从原始查询中删除连接谓词。

    在您看到连接谓词警告的情况下,SQL Server 在编译时检测到常量表只有一个不同的值,并且该值1将查询重写为

    SELECT *
    FROM   (SELECT *
            FROM   #temp1 t1
            WHERE  t1.i = 1) t1
           CROSS JOIN (SELECT 1 i
                       UNION ALL
                       SELECT 1) t2 
    

    表扫描上有一个谓词#temp如下[tempdb].[dbo].[#temp1].[i] =(1)

    on t1.i = t2.i当使用两个表或常量表包含多个不同的值时,无法在编译时以这种方式删除连接谓词。


    有关这方面的更多信息,请参阅Paul White的Query Optimizer Deep Dive系列。

    • 18

相关问题

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

  • 我在索引上放了多少“填充”?

  • 是否有开发人员遵循数据库更改的“最佳实践”类型流程?

  • 从 SQL Server 2008 降级到 2005

Sidebar

Stats

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

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

    • 3 个回答
  • Marko Smith

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

    • 3 个回答
  • Marko Smith

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

    • 4 个回答
  • Marko Smith

    授予用户对所有表的访问权限

    • 5 个回答
  • 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
    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
    pedrosanta 使用 psql 列出数据库权限 2011-08-04 11:01:21 +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