我试图通过访问具有约 2.5 亿条记录的表的查询来提高性能。从我对实际(未估计)执行计划的阅读来看,第一个瓶颈是如下所示的查询:
select
b.stuff,
a.added,
a.value
from
dbo.hugetable a
inner join
#smalltable b on a.fk = b.pk
where
a.added between @start and @end;
Run Code Online (Sandbox Code Playgroud)
有关所涉及的表和索引的定义,请进一步向下查看。
执行计划表明#smalltable 正在使用嵌套循环,并且对hugetable 的索引扫描执行了480 次(针对#smalltable 中的每一行)。这对我来说似乎是倒退,所以我试图强制使用合并连接:
select
b.stuff,
a.added,
a.value
from
dbo.hugetable a with(index = ix_hugetable)
inner merge join
#smalltable b with(index(1)) on a.fk = b.pk
where
a.added between @start and @end;
Run Code Online (Sandbox Code Playgroud)
有问题的索引(完整定义见下文)涵盖列fk(连接谓词)、added(在 where 子句中使用)和id(无用)按升序排列,并包括value。
然而,当我这样做时,查询从 2 1/2 分钟到超过 9 分钟。我本来希望提示会强制更有效的连接,只对每个表进行一次传递,但显然不是。
欢迎任何指导。如果需要,提供其他信息。
重新组织表上的索引后,我取得了显着的性能进步,但是在汇总大表中的数据时遇到了新的障碍。结果是按月汇总,目前如下所示:
select
b.stuff,
datediff(month, …Run Code Online (Sandbox Code Playgroud) 很久以前我遇到过这个问题,我找到了一个适合我的解决方法并忘记了它。
但是现在在 SO 上有这个问题,所以我愿意提出这个问题。
有一个视图以非常简单的方式(订单 + 订单行)连接几个表。
在没有where子句的情况下查询时,视图返回几百万行。
然而,从来没有人这样称呼它。通常的查询是
select * from that_nasty_view where order_number = 123456;
Run Code Online (Sandbox Code Playgroud)
这将返回 5m 中的大约 10 条记录。
一件重要的事情:视图包含一个窗口函数,rank(),它由始终查询视图所使用的字段精确分区:
rank() over (partition by order_number order by detail_line_number)
Run Code Online (Sandbox Code Playgroud)
现在,如果使用查询字符串中的文字参数查询此视图,完全如上所示,它会立即返回行。执行计划很好:
order_number(返回 10 行)。然而,当以参数化的方式调用视图时,事情变得很糟糕:
Index scan在所有表上忽略索引。返回 5m 行。partitions 的窗口(大约 500k 个窗口)。Filter 从 5m 中取出 10 行。在涉及参数的所有情况下都会发生这种情况。它可以是 SSMS:
declare @order_number int = 123456;
select * from that_nasty_view where order_number = @order_number; …Run Code Online (Sandbox Code Playgroud) 假设我们有一个对自身有外键约束的表,如下所示:
CREATE TABLE Foo
(FooId BIGINT PRIMARY KEY,
ParentFooId BIGINT,
FOREIGN KEY([ParentFooId]) REFERENCES Foo ([FooId]) )
INSERT INTO Foo (FooId, ParentFooId)
VALUES (1, NULL), (2, 1), (3, 2)
UPDATE Foo SET ParentFooId = 3 WHERE FooId = 1
Run Code Online (Sandbox Code Playgroud)
该表将有以下记录:
FooId ParentFooId
----- -----------
1 3
2 1
3 2
Run Code Online (Sandbox Code Playgroud)
在某些情况下,这种设计可能有意义(例如典型的“员工-老板-员工”关系),并且无论如何:我处于我的模式中有这种情况的情况。
不幸的是,这种设计允许数据记录中的循环,如上例所示。
那么我的问题是:
对于这个问题的第 (2) 部分,可能需要提及的是,我希望我的表中只有数百或在某些情况下可能有数千条记录,通常嵌套的深度不会超过大约 5 到 10 级。
附注。微软 SQL Server 2008
2012 年 3 月 14 日更新
有几个很好的答案。我现在已经接受了帮助我理解提到的可能性/可行性的那个。不过,还有其他几个很好的答案,其中一些还提供了实施建议,因此,如果您带着相同的问题来到这里,请查看所有答案;)
我在一个表中插入了两条记录。
create table num(id int)
insert into num values(0023)
insert into num values(23)
select * from num
Run Code Online (Sandbox Code Playgroud)
当我查询它们时,它们都显示为23. 这意味着 SQL Server 忽略前导 0。这背后的机制是什么?我如何让 SQL Server 在我插入它们时返回值(即0023和23)?
例如,有没有人成功地将“深色”它们应用于 SSMS 2008 的文本编辑器组件?
2005 年有一个旧技巧,它不再可操作且未升级。 http://winterdom.com/2007/10/colorschemesinsql2005managementstudio
我的眼睛会非常感谢你!干杯。
我之前使用过完全外部联接来获得我想要的结果,但也许我不完全理解这个概念,因为我无法完成应该是简单的联接。
我有 2 个表(我称之为 t1 和 t2),每个表有 2 个字段:
t1
Policy_Number Premium
101 15
102 7
103 10
108 25
111 3
Run Code Online (Sandbox Code Playgroud)
t2
Policy_Number Loss
101 5
103 9
107 20
Run Code Online (Sandbox Code Playgroud)
我想要做的是从两个表以及 Policy_Number 中获取 Premium 和 Sum of Losses 的总和。我正在使用的代码是:
select sum(premium) Prem_Sum, sum(Loss) Loss_Sum, t1.policynumber
from t1 full outer join t2 on t1.policynumber = t2.policynumber
group by t1.policynumber
Run Code Online (Sandbox Code Playgroud)
上面的代码将返回正确的总和,但它会将在“NULL”policy_number 下没有 policy_number 匹配的所有记录分组。
我希望我的结果看起来像这样
Policy_Number Prem_Sum Loss_Sum
107 NULL 20
111 3 NULL
101 15 5
Run Code Online (Sandbox Code Playgroud)
等等.....
我不想要显示 NULL policy_number …
我想更新我们数据库中的标量函数。此函数用于键表中的多个计算列,因此如果我尝试更新它,则会出现依赖项错误。我可以显式删除列,更新函数并重新添加列,但是,无需过多关注,这将更改列顺序并可能产生其他意想不到的后果。我想知道是否有更清洁的方法?
我有两张表用于存储:
IP 存储为bigints 以提高查找性能。
这是表结构:
create table [dbo].[ip2country](
[begin_ip] [varchar](15) NOT NULL,
[end_ip] [varchar](15) NOT NULL,
[begin_num] [bigint] NOT NULL,
[end_num] [bigint] NOT NULL,
[IDCountry] [int] NULL,
constraint [PK_ip2country] PRIMARY KEY CLUSTERED
(
[begin_num] ASC,
[end_num] ASC
)
)
create table Request(
Id int identity primary key,
[Date] datetime,
IP bigint,
CategoryId int
)
Run Code Online (Sandbox Code Playgroud)
我想获取每个国家/地区的请求细分,因此我执行以下查询:
select
ic.IDCountry,
count(r.Id) as CountryCount
from Request r
left join ip2country ic
on r.IP between ic.begin_num …Run Code Online (Sandbox Code Playgroud) 我们有一个 SQL Server 2008 数据库服务器(它恰好在 MS 故障转移群集下运行,但我认为这与此处无关)。
我们的应用程序运行 Hibernate 以进行数据库访问,自从我们最近从 v3.1 升级到 3.6 以来,我们经常遇到 SQL Server 崩溃(每 24-48 小时,但有时更频繁)。
有问题的具体问题似乎与内存有关。就在服务器崩溃之前(然后似乎由故障转移集群管理器自动重新启动),我们收到了这些错误的负载:
Error: 701, Severity: 17, State: 130.
There is insufficient system memory in resource pool 'internal' to run this query.
Run Code Online (Sandbox Code Playgroud)
也偶尔(但定期)的消息
Error: 17300, Severity: 16, State: 1. (Params:). The error is printed in terse mode because there was error during formatting. Tracing, ETW, notifications etc are skipped.
Run Code Online (Sandbox Code Playgroud)
错误:17312,严重性:16,状态:1。(参数:)。错误以简洁模式打印,因为格式化过程中出现错误。跟踪、ETW、通知等被跳过。
我还收到一些应用程序级别的错误,例如
java.sql.SQLException: A time out occurred while waiting to optimize the query. Rerun …Run Code Online (Sandbox Code Playgroud) 我LCK_M_S在使用 RCSI时看到等待共享锁 ( )。我的理解是这不应该发生,因为SELECTs在使用 RCSI 时不需要共享锁。
我怎样才能看到共享锁?是因为外键吗?
sql-server-2008 ×10
sql-server ×4
performance ×2
constraint ×1
crash ×1
functions ×1
hierarchy ×1
join ×1
locking ×1
ssms ×1
t-sql ×1
view ×1