我有一个相当复杂的连接的执行计划,它显示在一个表上执行索引查找,其中"实际行数"读数为~70,000,而实际上表中总共只有约600行(估计数量)行只有127).
请注意,所有统计信息都是最新的,查询的输入参数与编译proc时输入的参数完全相同.
为什么实际行数如此之高,"实际行数"的实际含义是什么?
我唯一的理论是,大量的行与嵌套循环有关,而且这个索引查找正在执行多次 - "实际行数"实际上代表了所有执行的总行数.如果是这种情况,估计的行数也意味着所有执行的总行数?
有没有人有查询通过SQL2005/2008的计划缓存来识别在其执行计划中有表/索引扫描的查询或存储过程?
我有一个Oracle 10.2.0.3数据库,以及这样的查询:
select count(a.id)
from LARGE_PARTITIONED_TABLE a
join SMALL_NONPARTITIONED_TABLE b on a.key1 = b.key1 and a.key2 = b.key2
where b.id = 1000
Run Code Online (Sandbox Code Playgroud)
表LARGE_PARTITIONED_TABLE(a)有大约500万行,并由查询中不存在的列分区.表SMALL_NONPARTITIONED_TABLE(b)未分区,并保存大约10000行.
统计数据是最新的,并且表a的列key1和key2中有高度平衡的直方图.
表a具有主键和列key1,key2,key3,key4和key5上的全局非分区唯一索引.
查询解释计划显示以下结果:
---------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
---------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 31 | 4 (0)| 00:00:01 |
| 1 | SORT AGGREGATE | | 1 | 31 | | |
| 2 | NESTED LOOPS | | …Run Code Online (Sandbox Code Playgroud) 有人可以帮我调整这个SQL查询吗?
SELECT a.BuildingID, a.ApplicantID, a.ACH, a.Address, a.Age, a.AgentID, a.AmenityFee, a.ApartmentID, a.Applied, a.AptStatus, a.BikeLocation, a.BikeRent, a.Children,
a.CurrentResidence, a.Email, a.Employer, a.FamilyStatus, a.HCMembers, a.HCPayment, a.Income, a.Industry, a.Name, a.OccupancyTimeframe, a.OnSiteID,
a.Other, a.ParkingFee, a.Pets, a.PetFee, a.Phone, a.Source, a.StorageLocation, a.StorageRent, a.TenantSigned, a.WasherDryer, a.WasherRent, a.WorkLocation,
a.WorkPhone, a.CreationDate, a.CreatedBy, a.LastUpdated, a.UpdatedBy
FROM dbo.NPapplicants AS a INNER JOIN
dbo.NPapartments AS apt ON a.BuildingID = apt.BuildingID AND a.ApartmentID = apt.ApartmentID
WHERE (apt.Offline = 0)
AND (apt.MA = 'M')
Run Code Online (Sandbox Code Playgroud)
.
以下是执行计划的样子:
.

我不明白的是为什么我要为NPapplicants进行索引扫描.我有一个涵盖BuildingID和ApartmentID的索引.不应该使用吗?
我正在编写具有相当复杂的数据集,大量连接的报告.为了简化问题,因为我基本上是一个面向对象的开发者,我一直在写小(通常是标量)函数来做到这一点可以通过参加到一个子查询所要做的工作.这种事:
SELECT
x.Name, x.userId,
... [more columns and joins]
dbo.CountOrders(x.userId)
FROM Customers x
WHERE ...
Run Code Online (Sandbox Code Playgroud)
这是好习惯吗?马虎?慢?我应该编写常规的 T-SQL来做这些事吗?
sql performance coding-style sql-server-2008 sql-execution-plan
我有一个执行以下操作的存储过程:
SELECT Id
INTO #temp
FROM table
WHERE ...
DELETE FROM #temp
INNER JOIN table2 ON a=b
WHERE ...
Run Code Online (Sandbox Code Playgroud)
但是它运行缓慢。当我尝试查看执行计划时,由于SQL Server Management Studio提示“消息208,级别16,状态0,第31行,无效的对象名称'#temp'”,因此无法执行。
有什么方法可以查看此类脚本的执行计划(或执行详细信息(而非计划))吗?
让我们有一个支付表,其中35列包含主键(autoinc bigint)和3个非聚集的非唯一indeces(每个在一个int列上).
在表的列中,我们有两个日期时间字段:
付款日期 datetime NOT NULL
EDIT_DATE datetime NULL
该表有大约1 200 000行.只有~1000行有edit_date column = null.9000行的edit_date不为null且不等于payment_date其他行有edit_date = payment_date
当我们运行以下查询1时:
select top 1 *
from payments
where edit_date is not null and (payment_date=edit_date or payment_date<>edit_date)
order by payment_date desc
Run Code Online (Sandbox Code Playgroud)

服务器需要几秒钟才能完成.但是如果我们运行查询2:
select top 1 *
from payments
where edit_date is not null
order by payment_date desc
Run Code Online (Sandbox Code Playgroud)

执行结束于数据库'tempdb'的日志文件已满.备份数据库的事务日志以释放一些日志空间.
如果我们用某些列替换*,请参阅查询3
select top 1 payment_date
from payments
where edit_date is not null
order by payment_date desc
Run Code Online (Sandbox Code Playgroud)

它也会在几秒钟内完成.
魔术在哪里?
编辑 …
当我在Oracle查询计划中看到类似的内容时:
HASH JOIN
TABLE1
TABLE2
Run Code Online (Sandbox Code Playgroud)
这两个表中的哪一个正在被散列?
Oracle文档引用了一个通常被散列的"较小"表,但是当在查询计划中显示时,是否保证散列表总是处于特定位置(顶部或底部子节点)?
在这样的查询中,我遇到了由错误的xpath(属性谓词中缺少'@')导致的性能问题:
从table中选择extractvalue(field,'// item [attr ="value"]'),其中field1 =:1;
我期待一个异常,但似乎Oracle接受这个特殊的xpath,有意义吗?
我试图针对该查询执行解释计划,但结果很奇怪,有人可以帮我理解吗?
我用这段代码重现了这个环境
SELECT * FROM V$VERSION;
/*
Oracle Database 11g Release 11.2.0.3.0 - 64bit Production
PL/SQL Release 11.2.0.3.0 - Production
"CORE 11.2.0.3.0 Production"
TNS for Linux: Version 11.2.0.3.0 - Production
NLSRTL Version 11.2.0.3.0 - Production
*/
create table TMP_TEST_XML(
id number,
content_xml xmltype
);
/
create unique index IDX_TMP_TEST_XML on TMP_TEST_XML(id);
/
declare
xml xmltype := xmltype('<root>
<a key="A">Aaa</a>
<b key="B">Bbb</b>
<c key="C">Ccc</c>
<d key="D">Ddd</d>
<e key="E">Eee</e>
<f key="F">Fff</f>
<g key="G">Ggg</g>
<h key="H">Hhh</h> …Run Code Online (Sandbox Code Playgroud) 我有以下查询:
DECLARE @application_number CHAR(8)= '37832904';
SELECT
la.LEASE_NUMBER AS lease_number,
la.[LEASE_APPLICATION] AS application_number,
tnu.[FOLLOWUP_CODE] AS note_type_code -- catch codes not in codes table
FROM [dbo].[lease_applications] la
LEFT JOIN [dbo].tickler_notes_uniq tnu ON tnu.[ACCOUNT_NUMBER] = la.[ACCOUNT_NUMBER]
WHERE la.LEASE_APPLICATION = @application_number
OR @application_number IS NULL;
SELECT
la.LEASE_NUMBER AS lease_number,
la.[LEASE_APPLICATION] AS application_number,
tnu.[FOLLOWUP_CODE] AS note_type_code -- catch codes not in codes table
FROM [dbo].[lease_applications] la
LEFT JOIN [dbo].tickler_notes_uniq tnu ON tnu.[ACCOUNT_NUMBER] = la.[ACCOUNT_NUMBER]
WHERE la.LEASE_APPLICATION = @application_number;
Run Code Online (Sandbox Code Playgroud)
这两个查询之间的唯一区别是,我添加了检查该变量是否为NULL的检查。
您可以在此处找到图形化计划
问题是。为什么计划如此不同?
更新: …
sql-server sqlperformance sql-execution-plan sql-server-2014
sql-server ×6
sql ×5
oracle ×3
performance ×3
coding-style ×1
indexing ×1
oracle10g ×1
t-sql ×1
xmltype ×1
xpath ×1