标签: sql-execution-plan

什么是SQL执行计划以及它们如何帮助我?

我最近听到很多,我应该看看我的SQL的执行计划,以判断它的执行情况.但是,我不确定从何处开始使用此功能或具体含义.

我正在寻找一个很好的解释执行计划的作用,它的局限性,以及我如何利用它或指向一个资源.

t-sql sql-server sql-execution-plan

8
推荐指数
1
解决办法
497
查看次数

SQL Developer解释计划中断了

试图在SQL Developer中生成解释计划,程序会弹出一个消息框,标题为"无法查询plan_table",抱怨"无效的列名".未生成或显示该计划.怎么修?

database oracle oracle-sqldeveloper sql-execution-plan

8
推荐指数
2
解决办法
7213
查看次数

LIKE'%...'如何寻求索引?

我希望这两个SELECTs具有相同的执行计划和性能.由于有一个领先的通配符LIKE,我希望进行索引扫描.当我运行它并查看计划时,第一个SELECT按预期运行(使用扫描).但第二个SELECT计划显示索引搜索,并且运行速度提高了20倍.

码:

-- Uses index scan, as expected:
SELECT 1
    FROM AccountAction
    WHERE AccountNumber LIKE '%441025586401'

-- Uses index seek somehow, and runs much faster:
declare @empty VARCHAR(30) = ''
SELECT 1
    FROM AccountAction
    WHERE AccountNumber LIKE '%441025586401' + @empty
Run Code Online (Sandbox Code Playgroud)

题:

当模式以通配符开头时,SQL Server如何使用索引查找?

奖金问题:

为什么连接空字符串会改变/改进执行计划?

细节:

  • 有一个非聚集索引 Accounts.AccountNumber
  • 还有其他索引,但搜索和扫描都在索引上.
  • Accounts.AccountNumber列可以为空varchar(30)
  • 服务器是SQL Server 2012

表和索引定义:

CREATE TABLE [updatable].[AccountAction](
    [ID] [int] IDENTITY(1,1) NOT NULL,
    [AccountNumber] [varchar](30) NULL,
    [Utility] [varchar](9) …
Run Code Online (Sandbox Code Playgroud)

sql wildcard sql-execution-plan sql-server-2012 sql-like

8
推荐指数
1
解决办法
3534
查看次数

有没有办法让 Oracle 为每个查询调用重新计算一个查询计划?

我有一个参数化查询。根据参数值的不同,最优查询计划会有很大差异。问题在于:Oracle 将第一次查询调用的计划用于后续调用,从而导致性能不佳。我通过动态 SQL 处理它,但这种方式远非优雅。所以问题是:有没有办法告诉 Oracle 必须重新计算查询计划?

oracle sql-execution-plan

7
推荐指数
2
解决办法
1万
查看次数

SQL Query执行快捷方式OR逻辑?

我有三张桌子:

SmallTable
   (id int, flag1 bit, flag2 bit)
JoinTable
   (SmallTableID int, BigTableID int)
BigTable
   (id int, text1 nvarchar(100), otherstuff...)
Run Code Online (Sandbox Code Playgroud)

SmallTable最多只有几十条记录.BigTable有几百万,实际上是一个视图,UNIONS在这个数据库中的一个表与同一服务器上的另一个数据库中的表.

这是连接逻辑:

SELECT * FROM
    SmallTable s
    INNER JOIN JoinTable j ON j.SmallTableID = s.ID
    INNER JOIN BigTable b ON b.ID = j.BigTableID
WHERE
    (s.flag1=1 OR b.text1 NOT LIKE 'pattern1%')
    AND (s.flag2=1 OR b.text1 <> 'value1')
Run Code Online (Sandbox Code Playgroud)

平均连接大小是几千个结果.显示的所有内容都已编入索引.

对于大多数SmallTable记录,flag1flag2设置为1,所以实际上甚至不需要访问BigTable.text1上的索引,但SQL Server无论如何都会这样做,导致代价高昂的索引扫描和嵌套循环.

有没有更好的方式来暗示到SQL Server,如果flag1flag2都被设置为1,它不应该甚至懒得看text1

实际上,如果我可以在这些情况下完全避免加入BigTable(管理JoinTable,这不会产生问题),这将使这个关键查询更快.

t-sql sql-server performance short-circuiting sql-execution-plan

7
推荐指数
1
解决办法
2987
查看次数

以编程方式读取SQL Server的查询计划建议的SQL特定执行索引?

如果我在SSMS中运行此命令:

set showplan_xml on
GO
exec some_procedure 'arg1', 'arg2','arg3'
GO
set showplan_xml off
GO
Run Code Online (Sandbox Code Playgroud)

我获得了查询执行中涉及的完整调用堆栈的XML输出,以及任何建议的索引等.

怎么可能从C#中读到这个?

(一个用例可能是定期启用此功能并在生产环境中记录这些结果,以便密切关注索引建议.)

c# sql-server sqlclr sql-execution-plan

7
推荐指数
1
解决办法
1238
查看次数

Postgresql索引seq扫描1亿行

我遇到的问题是,索引的查询拒绝使用索引,因为它没有足够的选择性(假设有1.3亿行中的60个符合条件),因此决定使用seqscan.

我面临的问题是seqscan在这种情况下真的不是最好的选择,由于某些原因它获得了非常好的分数,但事实是seqscan只有在之前被查询并且它可以加载所有内容时才能快速运行来自缓冲区/缓存.

与seqscan相比,索引扫描可能稍微慢一点,如果它们的两个都在缓冲区上,但这很少发生,当两个查询都很冷时,索引扫描仍然更快(ms vs秒).

请注意,索引扫描是优越的,因为我正在使用限制子句,因此它应该能够非常快速地获取这几行.

我已将统计值设置为1000(默认值为100)并且为了以防真空吸尘,但是相同的故事.

TLDR:Seq扫描与低选择性索引上的索引扫描,seqscan是首选,但规划者是错误的,seqscan只有在缓存时才会更好,否则会更糟.

查询和计划,请注意索引一是从缓冲区加载而seqscan不完全.

explain (analyze, buffers)
select *
from identities_identity
where email_domain = 'live.com'
limit 100


'Limit  (cost=0.00..63.50 rows=100 width=573) (actual time=75215.573..75215.640 rows=100 loops=1)'
'  Buffers: shared hit=75113 read=588870'
'  ->  Seq Scan on identities_identity  (cost=0.00..2980008.00 rows=4692733 width=573) (actual time=75215.571..75215.604 rows=100 loops=1)'
'        Filter: ((email_domain)::text = 'live.com'::text)'
'        Rows Removed by Filter: 54464136'
'        Buffers: shared hit=75113 read=588870'
'Planning time: 0.097 ms'
'Execution time: 75215.675 ms'


'Limit  (cost=0.57..187.26 rows=100 width=573) (actual time=0.027..0.090 rows=100 loops=1)'
' …
Run Code Online (Sandbox Code Playgroud)

postgresql indexing performance seq sql-execution-plan

7
推荐指数
1
解决办法
961
查看次数

为什么 Postgres EXPLAIN ANALYZEexecution_time 与我运行实际查询时不同?

我正在使用数据库客户端来测试。

使用EXPLAIN ANALYZE

Hash Join  (cost=5.02..287015.54 rows=3400485 width=33) (actual time=0.023..1725.842 rows=3327845 loops=1)
  Hash Cond: ((fact_orders.financial_status)::text = (include_list.financial_status)::text)
  CTE include_list
    ->  Result  (cost=0.00..1.77 rows=100 width=32) (actual time=0.003..0.004 rows=4 loops=1)
          ->  ProjectSet  (cost=0.00..0.52 rows=100 width=32) (actual time=0.002..0.003 rows=4 loops=1)
                ->  Result  (cost=0.00..0.01 rows=1 width=0) (actual time=0.000..0.000 rows=1 loops=1)
  ->  Seq Scan on fact_orders  (cost=0.00..240253.85 rows=3400485 width=38) (actual time=0.006..551.558 rows=3400485 loops=1)
  ->  Hash  (cost=2.00..2.00 rows=100 width=32) (actual time=0.009..0.009 rows=4 loops=1)
        Buckets: 1024  Batches: 1  Memory Usage: 9kB
        ->  CTE Scan on …
Run Code Online (Sandbox Code Playgroud)

sql postgresql query-optimization explain sql-execution-plan

7
推荐指数
1
解决办法
2770
查看次数

如何在加入/推送到外部服务器之前强制评估子查询

假设我想查询一个带有几个WHERE过滤器的大表。我正在使用 Postgres 11 和外部表;外部数据包装器 (FDW) 是clickhouse_fdw. 但我也对通用解决方案感兴趣。

我可以这样做:

SELECT id,c1,c2,c3 from big_table where id=3 and c1=2
Run Code Online (Sandbox Code Playgroud)

我的 FDW 能够对远程外部数据源进行过滤,确保上述查询快速并且不会拉取太多数据。

如果我写的话上面的效果是一样的:

SELECT id,c1,c2,c3 from big_table where id IN (3,4,5) and c1=2
Run Code Online (Sandbox Code Playgroud)

即所有的过滤都被发送到下游。

但是,如果我尝试执行的过滤稍微复杂一些:

SELECT bt.id,bt.c1,bt.c2,bt.c3
from big_table bt
join lookup_table l on bt.id=l.id
where c1=2 and l.x=5
Run Code Online (Sandbox Code Playgroud)

然后查询规划器决定远程过滤c1=2,但在本地应用另一个过滤器。

在我的用例中,先计算哪些ids 有l.x=5,然后将其发送出去进行远程过滤会快得多,所以我尝试按以下方式编写:

SELECT id,c1,c2,c3
from big_table
where c1=2
and id IN (select id from lookup_table where x=5)
Run Code Online (Sandbox Code Playgroud)

big_table然而,查询规划器仍然决定在本地对satisfy的所有结果执行第二个过滤器c1=2,这非常慢。

有什么方法可以“强制”(select …

sql postgresql sql-execution-plan postgresql-performance foreign-data-wrapper

7
推荐指数
1
解决办法
1948
查看次数

MySQl解释Extra“Using where”的真正含义是什么?

根据MySQL文档,使用where意味着:WHERE子句用于限制哪些行与下一个表匹配或发送到客户端。

据我了解,这意味着如果您的sql语句有where条件,则您的解释中会出现“Using where”额外信息。根据我的经验,这似乎意味着 MySQL 存储引擎发现索引无法覆盖某些列,并且必须检索行数据。例如:

在此输入图像描述

谁能解释一下Using where的真正含义?

mysql explain sql-execution-plan

7
推荐指数
1
解决办法
3849
查看次数