我350GB在我的电脑上运行一个数据库,大约有 4000 万行。
SQL Server 2014、Win7、AMD 8350 @ 4.8GHZ、16 GB RAM 和 500 GB SSD(数据库托管在它自己的 500 GB SSD 上,吞吐量为 500MB/500MB 读/写)。
数据库没有更新,我只是在分析/阅读它。与创建几个indexes,任何join,count(*)等等,只需要不到1分钟,这是确定我的目的。我一直在对数据运行一些查询(在运行单个连接查询后,40-50 次,它变得很慢),现在花了 1 分钟的调用,在 20 分钟后仍在运行。
我密切关注系统资源,我可以看到SSD查询开始时的启动,它读取 20-30 秒,然后121kB/second在接下来的 20 分钟读取。这不是 CPU 问题或磁盘问题。我的 RAM 数量有限,但是当我第一次加载数据库时调用运行良好,现在,25 分钟后没有任何运行。
实际上,我无法再查询数据库,任何调用都需要很长时间,即使是基本SELECT语句。我试过重建索引和更新统计信息,但没有区别。
我在这方面没有很多经验,所以我的 SQL 查询完全有可能不正确,在这种情况下,我希望出现错误,或者它以 0 结果完成执行,但两者都没有发生。
我想要做的是在基于表 ACALLS 的时间之前的 5 秒内计算“TypeID”的所有实例。
SELECT ACALLS.StartTime, ACALLS.Time, ACALLS.ServerIP, ACALLS.SRVR, ACALLS.calls, ACALLS.TOKEN, COUNT(TypeID) as ExecRate
FROM ACALLS
INNER JOIN MAINVIEW ON
MainView.TimeStamp …Run Code Online (Sandbox Code Playgroud) 对于这种特定情况,我将在下面尝试解释,使用表变量比不使用表变量性能更好。
我想知道为什么,如果可能的话,去掉表变量。
这是使用表变量的查询:
USE [BISource_UAT]
GO
set statistics io on
SET STATISTICS TIME ON
SET NOCOUNT ON;
DECLARE @OrderStartDate DATETIME = '15-feb-2015'
DECLARE @OrderEndDate DATETIME = '28-feb-2016'
DECLARE @tmp TABLE
(
strBxOrderNo VARCHAR(20)
,sintReturnId INT
)
INSERT INTO @tmp
SELECT strBxOrderNo
,sintReturnId
FROM TABLEBACKUPS.dbo.tblBReturnHistory rh
WHERE rh.sintReturnStatusId in ( 3 )
AND rh.dtmAdded >= @OrderStartDate
AND rh.dtmAdded < @OrderEndDate
SELECT
op.lngPaymentID
,op.strBxOrderNo
,op.sintPaymentTypeID
,op.strCurrencyCode
,op.strBCCurrencyCode
,op.decPaymentAmount
,op.decBCPaymentAmount
,ap.strAccountCode
,o.sintMarketID
,o.sintOrderChannelID
,o.sintOrderTypeID
,CASE WHEN opgv.lngpaymentID IS NULL THEN NULL
-- Not …Run Code Online (Sandbox Code Playgroud) performance sql-server sql-server-2014 temporary-tables table-variable query-performance
场景:SQL Server 2014 (v12.0.4100.1)
.NET 服务运行此查询:
SELECT name, base_object_name
FROM sys.synonyms
WHERE schema_id IN (SELECT schema_id
FROM sys.schemas
WHERE name = N'XXXX')
ORDER BY name
Run Code Online (Sandbox Code Playgroud)
...返回大约 6500 行,但通常在 3+ 分钟后超时。的XXXX上面是不“DBO”。
如果我以 UserA 的身份在 SSMS 中运行此查询,该查询将在不到一秒的时间内返回。
当以 UserB 运行(这是 .NET 服务连接的方式)时,查询需要 3-6分钟,并且 CPU%始终为 25%(4 核)。
UserA 是 sysadmin 角色中的域登录名。
UserB 是一个 SQL 登录,具有:
EXEC sp_addrolemember N'db_datareader', N'UserB'
EXEC sp_addrolemember N'db_datawriter', N'UserB'
EXEC sp_addrolemember N'db_ddladmin', N'UserB'
GRANT EXECUTE TO [UserB]
GRANT CREATE SCHEMA TO [UserB]
GRANT …Run Code Online (Sandbox Code Playgroud) 我是 DBA 的新手。我想知道表的行数中是否有任何指定的点,当我们到达该点时,我们就可以使用索引。我知道表的行数和使用索引之间应该有一些依赖关系,但我不知道是否有标准表的行数。
假设有一个带有聚集索引的表
create table [a_table] ([key] binary(900) unique clustered);
Run Code Online (Sandbox Code Playgroud)
和一些数据
insert into [a_table] ([key])
select top (1000000) row_number() over (order by @@spid)
from sys.all_columns a cross join sys.all_columns b;
Run Code Online (Sandbox Code Playgroud)
通过检查该表的存储统计
select st.index_level, page_count = sum(st.page_count)
from sys.dm_db_index_physical_stats(
db_id(), object_id('a_table'), NULL, NULL, 'DETAILED') st
group by rollup (st.index_level)
order by grouping_id(st.index_level), st.index_level desc;
Run Code Online (Sandbox Code Playgroud)
有人能看见
index_level page_count
----------- ----------
8 1
7 7
6 30
5 121
4 487
3 1952
2 7812
1 31249
0 125000
NULL 166659
Run Code Online (Sandbox Code Playgroud)
该表总共需要 166659 页。
然而表扫描 …
sql-server parallelism database-internals sql-server-2014 scan
所以我在 SQL Server 2014 中有一个存储事件的表。事件的生成速度不超过每 10 秒一次,但可能会慢得多(事件之间的几分钟或几小时)。事件之间的时间并不统一。
我想按时间对记录进行抽样。
例如,我想要求一个 10 分钟的采样 - 所以它会抓取记录 1,下一条记录应该是至少 10 分钟后的记录,然后下一条记录至少比第 2 行晚 10 分钟, 等等。
我可以通过迭代方法来实现这一点,循环遍历每条记录,但我想让数据库来完成这项工作。问题是,我不知道如何使用 T-SQL set/window 语句来做到这一点。
谁能帮我吗?
示例数据:
EventID | RecordTime
--------+--------------------
1 | 2017-04-01 12:00:00
2 | 2017-04-01 12:00:10
3 | 2017-04-01 12:00:20
4 | 2017-04-01 12:00:32
5 | 2017-04-01 12:05:42
6 | 2017-04-01 12:09:00
7 | 2017-04-01 12:24:12
8 | 2017-04-01 12:36:46
9 | 2017-04-01 12:36:57
10 | 2017-04-01 15:00:00
Run Code Online (Sandbox Code Playgroud)
想要的结果:
EventID | RecordTime
--------+--------------------
1 | 2017-04-01 12:00:00 …Run Code Online (Sandbox Code Playgroud) 我有一张不断更新的表,没有人能弄清楚更新的来源。我怀疑它们来自实体框架,但我想通过扩展事件捕获更新和相关信息来证明这个理论。
我正在使用 SQL 2014 Enterprise,并尝试使用 exec_prepared_sql 和 sql_statement_starting 事件捕获该信息。这是我到目前为止所拥有的:
CREATE EVENT SESSION [Query Trace] ON SERVER
ADD EVENT sqlserver.exec_prepared_sql(
ACTION(sqlserver.client_app_name,sqlserver.client_hostname,sqlserver.database_id,sqlserver.database_name,sqlserver.plan_handle,sqlserver.session_id,sqlserver.sql_text,sqlserver.username)
WHERE ([sqlserver].[like_i_sql_unicode_string]([sqlserver].[sql_text],N'%UPDATE %') AND [sqlserver].[like_i_sql_unicode_string]([sqlserver].[sql_text],N'%TableA%') AND [sqlserver].[database_id]=(123))),
ADD EVENT sqlserver.sql_statement_starting(
ACTION(sqlserver.client_app_name,sqlserver.client_hostname,sqlserver.database_id,sqlserver.database_name,sqlserver.plan_handle,sqlserver.session_id,sqlserver.sql_text,sqlserver.username)
WHERE ([sqlserver].[like_i_sql_unicode_string]([sqlserver].[sql_text],N'%UPDATE %') AND [sqlserver].[like_i_sql_unicode_string]([sqlserver].[sql_text],N'%TableA%') AND [sqlserver].[database_id]=(123)))
ADD TARGET package0.event_file(SET filename=N'E:\ExtendedEvent\Query-Trace.xel')
WITH (MAX_MEMORY=4096 KB,EVENT_RETENTION_MODE=ALLOW_SINGLE_EVENT_LOSS,MAX_DISPATCH_LATENCY=30 SECONDS,MAX_EVENT_SIZE=0 KB,MEMORY_PARTITION_MODE=NONE,TRACK_CAUSALITY=ON,STARTUP_STATE=OFF)
GO
Run Code Online (Sandbox Code Playgroud)
这似乎工作得很好,我已经对其进行了测试,并且能够捕获常规 UPDATE 语句和使用 sp_executesql 调用的语句。但是,我仍然缺少一些东西。表中的数据仍在修改,并且此扩展事件未捕获执行此操作的 UPDATE。
所以,我的问题是:
1) 为了捕获可能来自实体框架的更新,我还需要在扩展事件中观察其他什么吗?
2)为此我应该使用其他什么来代替扩展事件吗?
谢谢!
在尝试自动化包括 SSRS 报告和 SSRS 共享数据源/数据集的部署时,我们一直在尝试适当地配置安全性。特别是问题在于共享数据源/数据集以及在所有环境中自动部署它们。出现的唯一解决方案是创建单个 SQL Server 登录名,并使用与 SSRS 中共享数据源的数据源相同的用户名密码。从 Dev 到 Prod,帐户是相同的。
在所有这些环境中,新创建的 SQL 登录都需要对存储过程执行 EXECUTE。我反对在所有环境中使用 EXECUTE 权限进行一次 SQL 登录。
在更自动化的部署之前,我们在所有 3 个环境中都有一个帐户,但在生产中使用不同的密码。DBA 团队将在部署后手动更改共享数据源/数据集的密码。目标是摆脱手动干预,同时也不造成大的安全漏洞。
SSRS 配置文件已加密,但我不想创建具有如此多权限的 SQL 登录。还有其他选择吗?
下面是我在生产中遇到的事情的简化版本(在处理异常大量批次的一天,计划变得灾难性地更糟)。
已使用新的基数估计器针对 2014 年和 2016 年对 repro 进行了测试。
CREATE TABLE T1 (FromDate DATE, ToDate DATE, SomeId INT, BatchNumber INT);
INSERT INTO T1
SELECT TOP 1000 FromDate = '2017-01-01',
ToDate = '2017-01-01',
SomeId = ROW_NUMBER() OVER (ORDER BY @@SPID) -1,
BatchNumber = 1
FROM master..spt_values v1
CREATE TABLE T2 (SomeDateTime DATETIME, SomeId INT, INDEX IX(SomeDateTime));
INSERT INTO T2
SELECT TOP 1000000 '2017-01-01',
ROW_NUMBER() OVER (ORDER BY @@SPID) %1000
FROM master..spt_values v1,
master..spt_values v2
Run Code Online (Sandbox Code Playgroud)
T1 包含 1,000 行。
的FromDate,ToDate …
I have tables which are partitioned based on a INT column.
I see some queries that are using $Partition function to compare partition number instead of comparing the actual field data.
For example instead of saying:
select *
from T1
inner join T2 on T2.SnapshotKey = T1.SnapshotKey
Run Code Online (Sandbox Code Playgroud)
they have been written like below:
select *
from T1
inner join T2 on $Partition.PF_Name(T2.SnapshotKey) = $Partition.PF_Name(T1.SnapshotKey)
Run Code Online (Sandbox Code Playgroud)
where PF_Name is the name of partition function.
我看到对这些查询的评论说这样做是为了提高性能,当我运行这两个查询时,我看到执行时间和执行计划不同。我不确定这两个查询有何不同。
这是一个真正的查询:
-- this takes about 9 seconds …Run Code Online (Sandbox Code Playgroud) performance sql-server partitioning sql-server-2014 query-performance
sql-server-2014 ×10
sql-server ×9
performance ×3
index ×1
parallelism ×1
partitioning ×1
scan ×1
security ×1
ssrs ×1
t-sql ×1