标签: sql-execution-plan

如何解决SQL Server - 基于参数的内联表值函数执行计划变化?

下面是这样的情况:
我有一个带有datetime参数的表值函数,最好是tdf(p_date),它可以过滤大约200万行,选择列日期小于p_date的行,并计算其他列的某些聚合值.
它工作得很好,但是如果p_date是一个自定义标量值函数(在我的情况下返回结束日期),则执行计划会被更改,查询将从1秒执行到1分钟执行时间.

概念证明表 - 1K产品,2M行:

CREATE TABLE [dbo].[POC](
    [Date] [datetime] NOT NULL,
    [idProduct] [int] NOT NULL,
    [Quantity] [int] NOT NULL
) ON [PRIMARY]
Run Code Online (Sandbox Code Playgroud)

内联表值函数:

CREATE FUNCTION tdf (@p_date datetime)
RETURNS TABLE 
AS
RETURN 
(
    SELECT idProduct, SUM(Quantity) AS TotalQuantity,
         max(Date) as LastDate
    FROM POC
    WHERE (Date < @p_date)
    GROUP BY idProduct
)
Run Code Online (Sandbox Code Playgroud)

标量值函数:

CREATE FUNCTION [dbo].[EndOfDay] (@date datetime)
RETURNS datetime
AS
BEGIN
    DECLARE @res datetime
    SET @res=dateadd(second, -1,
         dateadd(day, 1, 
             dateadd(ms, -datepart(ms, @date),
                 dateadd(ss, -datepart(ss, @date),
                    dateadd(mi,- datepart(mi,@date),
                         dateadd(hh, …
Run Code Online (Sandbox Code Playgroud)

t-sql sql-server user-defined-functions sql-execution-plan

5
推荐指数
1
解决办法
2912
查看次数

SQL Server如何计算出估计的行数?

我正在尝试调试一个相当复杂的存储过程,它连接多个tabls(10-11).我看到,对于树的一部分,估计的行数与实际行数大不相同 - 在最差的SQL服务器估计将返回1行,而实际上返回55,000行!

我想弄清楚为什么会这样 - 我的所有统计数据都是最新的,我在几个表上用FULLSCAN更新了统计数据.我没有使用任何用户定义的函数或表变量.据我所知,SQL服务器应该能够准确估计将返回多少行,但它会继续选择一个计划,以便它执行数万次RDI查找(当它只期望执行1次时)或2).

我该怎么做才能尝试理解为什么估计的行数超出这么多?

更新:所以看一下这个计划,我发现了一个特别令人怀疑的节点 - 它使用以下预定表在表上扫描:

status <> 5
AND [type] = 1
OR [type] = 2
Run Code Online (Sandbox Code Playgroud)

这个谓词返回整个表(630行 - 表扫描本身它不是性能不佳的来源)但是SQL服务器的估计行数只有37个.然后SQL服务器继续用RDI做几个嵌套循环查找,索引扫描和索引搜索.这可能是我大量错误计算的根源吗?如何让它估计更合理的行数?

sql-server sql-server-2005 sql-execution-plan

5
推荐指数
1
解决办法
7567
查看次数

即使EXPLAIN显示良好的计划,MySQL也会加入慢速查询

我有以下场景:在MySQL数据库中,我有2个MyISAM表,一个有420万行,另一个有3.2亿行.以下是表的架构:

表1(4.2M行)

F1 INTEGER UNSIGNED NOT NULL PRIMARY KEY
f2 varchar(40)
f3 varchar(40)
f4 varchar(40)
f5 varchar(40)
f6 smallint(6)
f7 smallint(6)
f8 varchar(40)
f9 varchar(40)
f10 smallint(6)
f11 varchar(10)
f12 tinyint(4)
f13 smallint(6)
f14 text
Run Code Online (Sandbox Code Playgroud)

表2(320M行)

F1 INTEGER UNSIGNED NOT NULL PRIMARY KEY
f2 INTEGER UNSIGNED NOT NULL
Run Code Online (Sandbox Code Playgroud)

表2位于不同的数据库中,但我使用的是查询这两个表的存储过程.两个表之间的关系是Table1.F1可能最多约.Table2.F1(外键)中的100行匹配,并且将为这些匹配的键返回Table2.f2的值.我在表1上有一个索引IX1(f2(15),f3(10))和表2中的索引IX2(F1,f2)和IX3(f2)

我正在运行的查询如下:

SELECT g.F1
FROM DB1.Table1 g 
INNER JOIN DB2.Table2 gp ON g.F1 = gp.F1 
WHERE (gp.f2 = 452677825) AND
(g.f2 = 'A string value') LIMIT 0,56
Run Code Online (Sandbox Code Playgroud)

此查询有时非常快(<1s),但更改g.F2所比较的字符串值会导致查询甚至超过11秒甚至30秒.我不明白为什么会这样.以下是执行SELECT的EXPLAIN的输出.

1, 'SIMPLE', 'g', 'ref', …
Run Code Online (Sandbox Code Playgroud)

mysql performance join sql-execution-plan

5
推荐指数
1
解决办法
1265
查看次数

Oracle外键执行计划?

考虑以下(简单)情况:

CREATE TABLE PARENT (
    PARENT_ID INT PRIMARY KEY
);

CREATE TABLE CHILD (
    CHILD_ID INT PRIMARY KEY,
    PARENT_ID INT NOT NULL,
    FOREIGN KEY (PARENT_ID) REFERENCES PARENT (PARENT_ID)
);
Run Code Online (Sandbox Code Playgroud)

没有索引CHILD.PARENT_ID,因此修改/删除PARENT是昂贵的(Oracle需要执行全表扫描CHILD以强制执行参照完整性).然而,以下声明的执行计划......

DELETE FROM PARENT WHERE PARENT_ID = 1
Run Code Online (Sandbox Code Playgroud)

...不显示表扫描(SYS_C0070229是索引PARENT.PARENT_ID):

查询计划

我知道有很多方法可以查看所有未编制索引的FOREIGN KEY,但如果我能够"警告"查询执行计划本身的潜在问题(BTW,MS SQL Server以及可能的其他数据库那样做)会更好.

这可能在Oracle中吗?

如果重要的话,我正在使用Oracle 10.2.

oracle foreign-keys oracle10g sql-execution-plan

5
推荐指数
1
解决办法
1483
查看次数

找出运行缓慢的存储过程

可能重复:
如何查找最慢的查询

在Sql Server 2008中,是否有任何选项可以找出所有存储过程在所有存储过程中运行缓慢(当存储过程的数量非常大时.例如:500)

sql stored-procedures sql-server-2008-r2 sql-execution-plan

5
推荐指数
1
解决办法
5324
查看次数

如何在一对多关系中有效地检索数据

我遇到了一个问题,我需要运行一个Query,它应该从主表中获取一些行,并且如果主表的键存在于子表(关系一对多)中,则有一个指示符.

查询可能是这样的:

select a.index, (select count(1) from second_table b where a.index = b.index) 
from first_table a;
Run Code Online (Sandbox Code Playgroud)

这样我就可以得到我想要的结果(0 =在second_table中没有依赖记录,否则有),但我正在为从数据库中获取的每条记录运行一个子查询.我需要为至少三个类似的表得到这样一个指标,主要查询已经是至少两个表之间的一些内部联接......

我的问题是,是否有一些非常有效的方法来处理这个问题.我曾想过将记录保存在新列"first_table"中,但dbadmin不允许触发器并通过代码跟踪它是太冒险了.

解决这个问题的好方法是什么?

此查询的应用程序将用于两件事:

  1. 指示first_table中给定行的second_table中至少存在一行.它是在列表中指出它.如果第二个表中没有行,我将不会打开此指示器.
  2. 要搜索first_table中的所有行,这些行在second_table中至少有一行,或者在第二个表中没有行.

我刚发现的另一个选择:

select a.index, b.index 
from first_table a 
left join (select distinct(index) as index from second_table) b on a.index = b.index
Run Code Online (Sandbox Code Playgroud)

这样,如果b.index不存在,我将得到null(显示最终可以调整,我在这里关注查询性能).

这个问题的最终目标是为这种情况找到合适的设计方法.它经常发生,真正的应用程序是一个POS系统,以显示所有客户端,并在列表中有一个图标作为指示客户端已打开订单.

sql db2 sql-execution-plan

5
推荐指数
1
解决办法
5602
查看次数

**在SQL Server Management Studio中查看执行计划时的受限文本**

我正在审查执行计划,以了解存储过程为何运行缓慢.但是在执行计划窗口而不是Missing Indexes我得到的有用文本** Restricted Text **.

这让我好奇,因为我以前没见过它,也找不到谷歌搜索或者搜索SO的参考.

有人可以解释这是告诉我的,如果可能的话,如何不限制文本 - 我猜SSMS试图告诉我一些东西,但不管它试图告诉我的是非常冗长并被这个文本取代代替.

SQL Server Management Studio执行计划 - 受限制的文本

sql sql-server ssms sql-execution-plan

5
推荐指数
1
解决办法
769
查看次数

PostgreSQL解释计划中的成本测量有多可靠?

查询在具有1,100万行的大型表上执行.我已经ANALYZE在查询执行之前在表上执行了一个.

查询1:

SELECT *
FROM accounts t1
LEFT OUTER JOIN accounts t2 
    ON (t1.account_no = t2.account_no
        AND t1.effective_date < t2.effective_date)
WHERE t2.account_no IS NULL;
Run Code Online (Sandbox Code Playgroud)

解释分析:

Hash Anti Join  (cost=480795.57..1201111.40 rows=7369854 width=292) (actual time=29619.499..115662.111 rows=1977871 loops=1)
  Hash Cond: ((t1.account_no)::text = (t2.account_no)::text)
  Join Filter: ((t1.effective_date)::text < (t2.effective_date)::text)
  ->  Seq Scan on accounts t1  (cost=0.00..342610.81 rows=11054781 width=146) (actual time=0.025..25693.921 rows=11034070 loops=1)
  ->  Hash  (cost=342610.81..342610.81 rows=11054781 width=146) (actual time=29612.925..29612.925 rows=11034070 loops=1)
        Buckets: 2097152  Batches: 1  Memory Usage: 1834187kB
        ->  Seq Scan on …
Run Code Online (Sandbox Code Playgroud)

sql postgresql explain database-performance sql-execution-plan

5
推荐指数
1
解决办法
3185
查看次数

SQL错误:ORA-01039:对视图的基础对象的特权不足

我正在尝试使用以下查询获取视图的解释计划

explain plan for select * from SCHEMA1.VIEW1;
Run Code Online (Sandbox Code Playgroud)

但是我越来越

错误报告 -

SQL Error: ORA-01039: insufficient privileges on underlying objects of the view

01039. 00000 -  "insufficient privileges on underlying objects of the view"


*Cause:    Attempting to explain plan on other people's view without
           the necessary privileges on the underlying objects of the view.


*Action:   Get necessary privileges or do not perform the offending operation.
Run Code Online (Sandbox Code Playgroud)

在获取SQL授权语句时需要帮助

database oracle view grant sql-execution-plan

5
推荐指数
1
解决办法
9235
查看次数

Apache Cassandra CQL查询解释计划

如何获得CQL查询的执行计划(或类似的smth)?我找不到任何关于CQL查询优化/执行的整合文档.

例如,我想知道,执行查询有什么不同,例如:

select some_column from SOME_TABLE where 
pkField='val1' 
and timestampField='date' 
allow filtering;
Run Code Online (Sandbox Code Playgroud)

select some_column from SOME_TABLE where 
pkField='val1' 
and timestampField<='date' 
and timestampField>='date' 
allow filtering;
Run Code Online (Sandbox Code Playgroud)

cql cassandra sql-execution-plan

5
推荐指数
1
解决办法
3152
查看次数