我有两个查询,如下所示,它们做同样的事情。这xmlcolumn是一个数据类型为 XML 的列。我使用这些查询在 XML 列中的任何位置搜索字符串。
我检查了这两个查询的执行计划,发现第一个查询的 I/O 成本和子树成本低于第二个。我原以为第一个会在使用cast和 时具有更高的成本charindex,但事实并非如此。
为什么它的成本更低?
第一个查询:
SELECT *
FROM mytable
WHERE ( Charindex('abc',CAST([xmlcolumn] AS VARCHAR(MAX)))>0 )
Run Code Online (Sandbox Code Playgroud)
第二个查询:
SELECT *
FROM mytable t1
WHERE t1.[xmlcolumn].exist('//*/text()[contains(.,"abc")]')=1
Run Code Online (Sandbox Code Playgroud) 我有以下查询explain:
mysql> explain
select dd.data from dane dd
join test1.tag1 t1 on dd.id = t1.id
join test1.tag2 t2 on dd.id = t2.id
join test1.tag3 t3 on dd.id = t3.id
join test1.tag4 t4 on dd.id = t4.id
join test1.tag5 t5 on dd.id = t5.id
join test1.tag6 t6 on dd.id = t6.id
join test1.tag7 t7 on dd.id = t7.id
join test1.tag8 t8 on dd.id = t8.id
join test1.tag9 t9 on dd.id = t9.id
join test1.tag10 t10 on dd.id = t10.id …Run Code Online (Sandbox Code Playgroud) 我从计划缓存中提取了一个执行计划,并从 XML 中提取了编译值。然后我使用编译后的值在 SSMS 中运行查询,即使查询计划针对同一个数据库运行,查询计划也不同。
任何人都可以解释为什么会发生这种情况吗?
有没有办法提取查询中使用的表和视图的完整列表?
我需要复制数据库的一部分,以便在长查询运行时避免锁定表。
我有执行计划。是否可以提取查询涉及的所有数据库对象?
我有一个表格[order],其中一个简单的选择以一种奇怪的方式显示了估计行数和实际行数之间的主要差异。
在这种情况下,一般估计行数与实际行数相比偏斜,这完全具有讽刺意味。此外,“执行次数”为 1。
询问 :
SELECT
ord.paymentmode AS [HowTheyPaid],
ord.id AS [OrderId],
ord.ISBackEndSystemMigrated,
ord.ISDuplicate,
ord.ISMerged
FROM
DedicatedDentalPlans_Stage.dbo.[order] ord
WHERE
ISBackEndSystemMigrated=0
AND ISDuplicate = 1
Run Code Online (Sandbox Code Playgroud)
桌子
USE [DedicatedDentalPlans_Stage]
GO
IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[DF_Order_ISBackEnd]') AND type = 'D')
BEGIN
ALTER TABLE [dbo].[Order] DROP CONSTRAINT [DF_Order_ISBackEnd]
END
GO
IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[DF__Order__ISDuplica__382F5661]') AND type = 'D')
BEGIN
ALTER TABLE [dbo].[Order] DROP CONSTRAINT [DF__Order__ISDuplica__382F5661]
END
GO
IF EXISTS (SELECT * …Run Code Online (Sandbox Code Playgroud) 我有一个标量函数,它返回一个大的 XML,它是通过一堆发票创建的。
可以使用几种不同的方法计算要提供给函数的确切发票列表,但函数每次都是相同的。出于这个原因,我声明了一个用户定义的表类型来包含表中的主键eInvoice.Header并将其传递给函数。这样我就可以有几个不同的函数来决定要处理哪些发票,并且只有一个函数可以实际生成 XML:
create function eInvoice.GetRelevantLinesInOneWay()
returns table ...
create function eInvoice.GetRelevantLinesInAnotherWay()
returns table ...
create function eInvoice.GetXML(@lines eInvoice.InvoicePrimaryKeys readonly)
returns xml
as
begin
declare @x xml;
with xmlnamespaces(N'important namespace' as pro)
select @x = (
select
...
from
eInvoice.Header h
inner join @lines l on h.ST_PRIMARY = l.invoice_row_id
for xml path(N'pro:Import'), type
);
return @x;
end;
Run Code Online (Sandbox Code Playgroud)
不幸的是,这种设置已被证明是非常脆弱的。
通常@lines包含大约 150 行(大约1min eInvoce.Header)。正确的执行计划是在 上使用索引查找ST_PRIMARY,当我将 的主体eInvoice.GetXML作为临时查询执行时,总是会发生这种情况。
然而,当我将它存储为一个函数时,它会按预期工作一段时间,然后发生了一些事情(太多行@lines,比如大约300 …
performance sql-server execution-plan sql-server-2012 table-valued-parameters query-performance
我有大约 150 万条记录。此查询适用于较小的数据,但每几十万条记录就会慢一秒。对于 150 万,查询明显困难。
我模拟了一个全新的 Code First 项目来验证问题与我的实现无关,并提供以下示例查询:
SELECT TOP 1 Widgets.*
FROM [WidgetSandbox].[dbo].[Widgets] Widgets
INNER JOIN [WidgetSandbox].[dbo].[Status] Statuses ON Widgets.StatusId = Statuses.Id
INNER JOIN [WidgetSandbox].[dbo].[Colors] Colors ON Widgets.ColorCode = Colors.ColorCode
INNER JOIN [WidgetSandbox].[dbo].[Sizes] Sizes ON Widgets.SizeId = Sizes.Id
WHERE Statuses.Name = 'Available'
AND Colors.Name = 'Red'
ORDER BY Sizes.DiameterInches
Run Code Online (Sandbox Code Playgroud)
DiameterInches 是一个int, 作为我实际代码中“PriorityLevel”的隐喻。
如果我注释掉ORDER BY Sizes.DiameterInches,它会立即返回,但如果我想找到“最小的可用红色小部件”,它就会爬行。
有没有更好的办法?
执行计划 XML:https : //gist.github.com/RobertBaldini/57c8b61d135cc5c84c38b2da243611ad
DDL:https : //gist.github.com/RobertBaldini/3740c7bb85eea47d7fe63cb8602ac2d6
回购(数据加载器需要几分钟):https : //github.com/RobertBaldini/WidgetSandbox
请帮助我,删除“使用临时”。我尝试了许多不同的选择,无法摆脱。或排序消失或出现“使用临时”。;(
分类表:
`product_category_multi` (
`m_Id` mediumint(7) NOT NULL,
`prod_Id` smallint(6) unsigned NOT NULL,
`multi_cat` mediumint(7) unsigned NOT NULL
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
Run Code Online (Sandbox Code Playgroud)
索引表:
ALTER TABLE `product_category_multi`
ADD PRIMARY KEY (`m_Id`),
ADD KEY `multi_cat` (`multi_cat`),
ADD KEY `Id` (`prod_Id`);
Run Code Online (Sandbox Code Playgroud)
示例内容表:
m_Id prod_Id multi_cat
-------+-----------+---------+
1 1 5
2 1 1
3 1 6
4 2 5
5 2 1
6 3 5
7 4 5
8 4 6
Run Code Online (Sandbox Code Playgroud)
产品表:
`shop_product` (
`Id` int(10) unsigned NOT NULL,
`product_article` varchar(20) NOT NULL,
`product_article_main` …Run Code Online (Sandbox Code Playgroud) 我正在尝试找出具有Probe Residual.
需要了解以下内容
Probe Residual 以下是我的一次尝试——但我被困在获取其他细节上。如何获取这些详细信息?
注意:我使用的是 SQL Server 2012
WITH XMLNAMESPACES
(
DEFAULT 'http://schemas.microsoft.com/sqlserver/2004/07/showplan'
)
SELECT
DECP.cacheobjtype,
DECP.objtype,
DECP.plan_handle,
DEQP.objectid,
DEQP.query_plan,
DEST.[text]
FROM sys.dm_exec_cached_plans AS DECP
CROSS APPLY sys.dm_exec_query_plan(DECP.plan_handle) AS DEQP
CROSS APPLY sys.dm_exec_sql_text(DECP.plan_handle) AS DEST
WHERE
1 = DEQP.query_plan.exist(
'//RelOp[
@PhysicalOp = "Hash Match"
]')
Run Code Online (Sandbox Code Playgroud)
甲探头残余例
下面引用 Grant Fritkey 和 Rob Farley 的博客/文章
我清除了我的统计数据并运行了我的查询。实际执行计划的总估计成本为 0.61。我使用dmv 中的total_worker_time列dm_exec_query_stats来计算平均 20858 微秒的 CPU 时间:
(SUM(query_stats.total_worker_time) / SUM(query_stats.execution_count))
Run Code Online (Sandbox Code Playgroud)
该计划推荐了一个索引,我创建了该索引。我清除了我的统计信息,然后再次运行查询。这一次,该计划在顶层的总估计成本为 0.37。我dm_exec_query_state再次检查了dmv,现在平均 CPU 时间为 51536 微秒。
我原以为工人的时间大约是一半,而不是两倍!我在这里错过了什么吗?为什么查询计划的改进没有反映在 exec 查询统计信息中?两个计划在这里上传:
execution-plan ×10
sql-server ×7
performance ×4
mysql ×2
xml ×2
explain ×1
index ×1
plan-cache ×1
t-sql ×1