我有一个观点,complicated_view-- 有一些连接和 where 子句。现在,
select * from complicated_view (9000 records)
Run Code Online (Sandbox Code Playgroud)
更快,更快,比
select top 500 * from complicated_view
Run Code Online (Sandbox Code Playgroud)
我们说的是 19 秒对 5+ 分钟。
第一个查询返回所有 9000 条记录。如何只获得前 500 名的时间长得可笑?
显然,我将在这里查看执行计划 ---- 但是一旦我弄清楚为什么SQL Server 以次优方式运行“前 500”,我该如何实际告诉它以快速方式运行计划,喜欢坐满桌?
当然,我可能不得不完全重写视图——但很奇怪。
基本上,我将此数据表连接到第 3 方软件,该软件使用select top 500 *无法修改的默认查询预先检查表。因此,除了将此视图转储到实际表中(非常草率)之外,我也无法绕过他们的“前 500 名”附录。
这是 SQL Server 2012。
编辑:不同意重复标志。另一个问题,顶部比所有的都快。这将是预期的行为,返回较少的行。我的情况正好相反。另外,我的理解是 Top 100 是一种与 Top 100+ 不同的算法。我什至不认为重复的问题有正确的答案。也就是说,TOP X 查询将在很早的时候对潜在的大量表进行排序,而不是在它们被聚合/过滤/等之后。为什么是一个谜,但如何显然存在。
performance sql-server execution-plan select top query-performance
我们有一个大约 1TB 的大型数据库,在强大的服务器上运行 SQL Server 2014。几年来,一切都运行良好。大约 2 周前,我们进行了全面维护,其中包括: 安装所有软件更新;重建所有索引和压缩 DB 文件。但是,我们没想到在某个阶段,在实际负载相同的情况下,DB 的 CPU 使用率会增加超过 100% 到 150%。
经过大量的故障排除,我们将其缩小到一个非常简单的查询,但我们找不到解决方案。查询非常简单:
select top 1 EventID from EventLog with (nolock) order by EventID
Run Code Online (Sandbox Code Playgroud)
它总是需要大约 1.5 秒!但是,使用“desc”的类似查询总是需要大约 0 毫秒:
select top 1 EventID from EventLog with (nolock) order by EventID desc
Run Code Online (Sandbox Code Playgroud)
PTable 大约有 5 亿行;EventID是ASC数据类型为 bigint(身份列)的主聚集索引列(ordered )。顶部有多个线程向表中插入数据(较大的 EventID),底部有 1 个线程删除数据(较小的 EventID)。
在 SMSS 中,我们验证了两个查询始终使用相同的执行计划:
聚集索引扫描;
估计行数和实际行数均为1;
估计和实际执行次数均为1;
估计I/O成本是8500(好像有点高)
如果连续运行,则两者的查询成本相同 50%。
我更新了索引统计with fullscan,问题依旧;我再次重建索引,问题似乎消失了半天,但又回来了。
我打开了 IO 统计:
set statistics io on …Run Code Online (Sandbox Code Playgroud) performance sql-server select sql-server-2014 top query-performance
你如何查询三个最大的唯一客户Purchase_Cost?
我想应用DISTINCT唯一的 on Customer_Name,但下面的查询在所有三列上应用不同的。我应该如何修改查询以获得所需的输出?
SELECT DISTINCT TOP 3 customer_name, order_no, Purchase_Cost
FROM PurchaseTable
ORDER BY Purchase_Cost
Run Code Online (Sandbox Code Playgroud)
我正在使用以下代码来提取前 20 个查询(按 CPU 排序):
SELECT TOP 20 qs.sql_handle
,qs.execution_count
,qs.total_worker_time AS [Total CPU]
,qs.total_worker_time / 1000000 AS [Total CPU in Seconds]
,(qs.total_worker_time / 1000000) / qs.execution_count AS [Average CPU in Seconds]
,qs.total_elapsed_time
,qs.total_elapsed_time / 1000000 AS [Total Elapsed Time in Seconds]
,st.TEXT
,qp.query_plan
FROM sys.dm_exec_query_stats AS qs
CROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) AS st
CROSS APPLY sys.dm_exec_query_plan(qs.plan_handle) AS qp
ORDER BY qs.total_worker_time DESC
Run Code Online (Sandbox Code Playgroud)
但是,我看到的是:

任何人都可以解释为什么查询计划和 SQL 文本显示为 NULL?它们是某种系统进程还是外部应用程序?我们正在运行 SQL 2008 R2。
谢谢大家,一如既往!
我有按月临时表的产品销售。(更大的历史表的子集)我正在运行查询以查找在指定的 6 个月范围内之前几个月未售出的新产品。因此,以 1 月为基础,在 2 月向我展示所有未在 1 月销售中销售的新产品。3 月所有未售出的新产品 1 月或 2 月销售等。前 5 个月查询返回次秒。第 6 个月,大约需要 5 分钟。比较执行计划,在第 6 个月,它显示我的执行计划中的 Top 运算符花费了额外的时间。但我没有在选择中排序或使用 Top X。我的查询中是什么导致了这种情况?我可以等 5 分钟,因为它是一次性请求,但我更多是从学习的角度询问,我想了解它为什么添加到 Top 运算符。提前致谢。
select divn_nbr, dept_nbr, vendorNumber, pid, nrfcolorNumber, periodcode
from ##tmpSFA a
where periodCode = '201512'
and not exists
(
select 1 from ##tmpSFA b
where ISNULL(a.divn_nbr, -99) = isnull(b.divn_nbr, -99)
and isnull(a.dept_nbr, -99) = isnull(b.dept_nbr, -99)
and isnull(a.vendorNumber, -99) = isnull(b.vendorNumber, -99)
and isnull(LTRIM(rtrim(upper(a.pid))), -99) = isnull(LTRIM(rtrim(upper(b.pid))), -99)
and isnull(a.nrfcolorNumber, -99) …Run Code Online (Sandbox Code Playgroud) 假设我有以下数据:
| f1 | f2 | f3 |
|----|----|----|
| 1 | 1 | 1 |
| 1 | 1 | 5 |
| 1 | 2 | 3 |
| 1 | 2 | 6 |
| 1 | 3 | 4 |
| 1 | 3 | 7 |
| 2 | 1 | 2 |
| 2 | 1 | 22 |
| 2 | 2 | 3 |
| 2 | 2 | 4 |
Run Code Online (Sandbox Code Playgroud)
每个 …
我正在尝试编写一个有效的查询来删除数据块。为此,我希望通过使用主键来获取最旧的记录来避免索引扫描。但是,我看到返回了一些意想不到的结果。
我希望这个
SELECT TOP 15 OrderID FROM [Order]
Run Code Online (Sandbox Code Playgroud)
会给我最旧的 15 条记录,因为我可以依靠主键递增,因此表中的存储顺序将从低到高。
但是,这会返回不同的结果集
SELECT TOP 15 OrderID FROM [Order] ORDER BY DateCreated ASC
Run Code Online (Sandbox Code Playgroud)
这似乎是获得我需要的结果的更准确但更昂贵的方式。
令人费解的是,这
SELECT TOP 15 * FROM [Order]
Run Code Online (Sandbox Code Playgroud)
为此提供一组不同的 OrderID (PK)
SELECT TOP 15 OrderID FROM [Order]
Run Code Online (Sandbox Code Playgroud)
我知道http://msdn.microsoft.com/en-gb/library/ms189463.aspx解释说没有 ORDER BY 子句就不能保证订单,但期望 PK 为我订购并且无法解释两者之间的差异最后两个选择子句。
我正在尝试优化查询以更快地运行。查询如下:
SELECT grp_fk_obj_id, grp_name
FROM tbl_groups as g1
CROSS APPLY (SELECT TOP 1 grp_id as gid
FROM tbl_groups as g2
WHERE g1.grp_fk_obj_id = g2.grp_fk_obj_id
ORDER BY g2.date_from DESC, ISNULL(date_to, '4000-01-01') DESC) as a
WHERE g1.grp_id = gid
Run Code Online (Sandbox Code Playgroud)
grp_id 是主键。grp_fk_obj_id 是另一个对象的外键。这两列都有索引(我猜它是默认的)。
完成大约需要半秒钟,但我需要它来加快工作速度。我查看了执行计划,它显示“Top N 排序”的成本超过 90%。另外,我注意到,如果我删除了交叉应用中的 where 子句,那么它的运行速度至少要快 5 倍,但我需要以一种或另一种方式使用 where 子句。
您是否认为有可能提高此查询的性能?
编辑:表创建 DDL:
create table tbl_groups
(
grp_id bigint identity
constraint PK_tbl_groups
primary key,
grp_fk_obj_id bigint not null
constraint FK_grp_fk_obj_id
references tbl_other,
grp_name varchar(30) not null,
date_from date not null, …Run Code Online (Sandbox Code Playgroud) 我有一个 500 行的结果集,但这是 100 张发票。我只需要最后一张发票的前 10 个。
我发现了类似的东西:如何从每个类别中选择前 10 条记录
样本数据:
InvNr | DetailLine
111 | 1
111 | 2
112 | 1
112 | 2
112 | 3
113 | 1
113 | 2
114 | 1
115 | 1
... | ...
Run Code Online (Sandbox Code Playgroud)
我希望得到的是例如:
SELECT DISTINCT TOP 2 InvNr, DetailLine FROM tbl_Invoice
Run Code Online (Sandbox Code Playgroud)
有了这个结果:
InvNr | DetailLine
111 | 1
111 | 2
112 | 1
112 | 2
112 | 3
Run Code Online (Sandbox Code Playgroud)
更新:
所以我需要他们创建的最后 10 个(或上例中的前 2 个)发票,但每个发票可以有“x”个明细行,我希望结果中的所有明细行(最后 10 …
如何拥有一个允许消费者有选择地指定返回行数的存储过程?
如果未指定行数,则返回所有行。
我有一个疑问:
select * from Aview where field=20
order by id desc
Run Code Online (Sandbox Code Playgroud)
这将在大约 1 秒内从视图中返回 2700 行。
在查询中添加“top 20”使 MSSQL 在 43 秒内返回!
这是一个很难重现的问题,重建统计数据可以修复该问题几天,但随后又回来了。
我使用 SQL 已经有几十年了,我从未见过添加“top”导致时间增加的情况。
查看执行计划,如果执行前 20 条,它似乎正在执行 9.6 亿行的惰性假脱机操作,但如果不执行,则不会执行。
top ×11
sql-server ×10
performance ×2
select ×2
cross-apply ×1
distinct ×1
dmv ×1
group-by ×1
sorting ×1
t-sql ×1
table-spool ×1