我有一个类似于这样的子表:
[客户日期表]
| Customer ID | Some Date | Balance |
+-------------+------------+---------+
| 1 | 2012-04-30 | 20.00 |
| 1 | 2012-03-31 | 50.00 |
| 2 | 2012-04-30 | 0.00 |
| 2 | 2012-03-31 | 10.00 |
| 3 | 2012-03-31 | 60.00 |
| 3 | 2012-02-29 | 10.00 |
Run Code Online (Sandbox Code Playgroud)
我希望能够获得这样的结果集 - 每个客户端的最新日期记录:
| Customer ID | Some Date | Balance |
+-------------+------------+---------+
| 1 | 2012-04-30 | 20.00 |
| 2 | 2012-04-30 | 0.00 …Run Code Online (Sandbox Code Playgroud) 考虑到优化器不能花它需要的所有时间(它必须最小化执行时间而不是贡献它)来探索所有可能的执行计划,它有时会被切断。
我想知道这是否可以覆盖以便您可以在需要时(或一定数量的毫秒)始终提供优化器。
我不需要这个(atm),但我可以想象一个场景,一个复杂的查询在一个紧密的循环中执行,你想提出最佳计划并事先缓存它。
当然,你有一个紧密的循环,你应该重写查询,这样它就会消失,但请耐心等待。
这更多是出于好奇而提出的问题,也是为了查看短路优化和完整优化之间有时是否存在差异。
事实证明,您可以使用跟踪标志 2301 为优化器提供更多时间。这不完全是我所要求的,但它很接近。
我在这方面找到的最佳信息是Ian Jose 的SQL Server 2005 SP1中的查询处理器建模扩展。
小心使用这个跟踪标志!但是在提出更好的计划时它会很有用。也可以看看:
我正在考虑具有大量连接的查询,其中连接顺序的解决方案空间呈指数级增长。SQL Server 使用的启发式方法非常好,但我想知道如果优化器有更多时间(在几秒甚至几分钟的范围内),它是否会提出不同的顺序。
上下文
我们正在开发一个底部有一个大型数据库的系统。它是在 SQL Server 2008 R2 上运行的 MS SQL 数据库。数据库的总大小约为 12 GB。
其中,单个表中大约有 8.5 GB BinaryContent。顾名思义,这是一个表,我们将任何类型的简单文件作为 BLOB 直接存储在表中。最近,我们一直在测试使用 FILESTREAM 将所有这些文件从数据库移到文件系统的可能性。
我们对数据库进行了必要的修改,没有任何问题,迁移后我们的系统仍然运行良好。该BinaryContent表大致如下所示:
CREATE TABLE [dbo].[BinaryContent](
[BinaryContentID] [int] IDENTITY(1,1) NOT NULL,
[FileName] [varchar](50) NOT NULL,
[BinaryContentRowGUID] [uniqueidentifier] ROWGUIDCOL NOT NULL
) ON [PRIMARY] FILESTREAM_ON [FileStreamContentFG]
ALTER TABLE [dbo].[BinaryContent] ADD [FileContentBinary] [varbinary](max) FILESTREAM NULL
ALTER TABLE [dbo].[BinaryContent] ADD CONSTRAINT [DFBinaryContentRowGUID] DEFAULT (newsequentialid()) FOR [BinaryContentRowGUID]
Run Code Online (Sandbox Code Playgroud)
PRIMARY除了FileBinaryContent位于单独文件组中的字段外,所有内容都驻留在文件组中FileStreamContentFG。
场景
从开发人员的角度来看,我们通常希望从我们的生产环境中获得一个新的数据库副本,以便能够处理最新的数据。在这些情况下,我们很少对存储在BinaryContent(现在使用 FILESTREAM)。
我们几乎可以按照我们的意愿工作。我们备份数据库,没有像这样的文件流:
BACKUP DATABASE FileStreamDB
FILEGROUP …Run Code Online (Sandbox Code Playgroud) 我有一个带有“TOP (X)”子句的 SQL UPDATE 语句,我正在更新值的行大约有 40 亿行。当我使用“TOP (10)”时,我得到一个几乎立即执行的执行计划,但是当我使用“TOP (50)”或更大时,查询永远不会(至少,在我等待时不会)完成,并且它使用完全不同的执行计划。较小的查询使用带有一对索引查找和嵌套循环连接的非常简单的计划,其中完全相同的查询(在 UPDATE 语句的 TOP 子句中具有不同的行数)使用涉及两个不同索引查找的计划、表线轴、并行性和一堆其他复杂性。
我使用了“OPTION (USE PLAN...)”来强制它使用由较小查询生成的执行计划——当我这样做时,我可以在几秒钟内更新多达 100,000 行。我知道查询计划很好,但 SQL Server 只会在只涉及少量行时自行选择该计划 - 我的更新中任何相当大的行数都会导致次优计划。
我认为并行性可能是罪魁祸首,所以我设置MAXDOP 1了查询,但没有效果 - 这一步已经消失,但糟糕的选择/性能没有。我sp_updatestats今天早上也跑了,以确保这不是原因。
我附上了两个执行计划 - 越短的执行计划也越快。此外,这里是有问题的查询(值得注意的是,我包含的 SELECT 在小行数和大行数的情况下似乎都很快):
update top (10000) FactSubscriberUsage3
set AccountID = sma.CustomerID
--select top 50 f.AccountID, sma.CustomerID
from FactSubscriberUsage3 f
join dimTime t
on f.TimeID = t.TimeID
join #mac sma
on f.macid = sma.macid
and t.TimeValue between sma.StartDate and sma.enddate
where f.AccountID = 0 --There's a filtered index …Run Code Online (Sandbox Code Playgroud) 事件通知有问题。在消息发送到的机器/驱动器/数据库(接收器)上,驱动器在没有人查看时已满,因此它已经备份了一整天。
现在我们释放了驱动器上的空间,它正在接受消息进入队列,但它似乎没有处理它们 - 没有插入新记录,即使队列现在有 2200 万条消息并且还在增长(!)。队列已启用:
is_activation_enabled = 1
is_receive_enabled = 1
is_enqueue_enabled = 1
Run Code Online (Sandbox Code Playgroud)
我在 中看到激活的 SP activation_procedure,但是当我在 中查看时SP_WHOISACTIVE,我没有看到任何活跃的阅读器。
在我再次炸毁驱动器之前 - 我做错了什么?我怎样才能让它处理或刷新消息?提前致谢。
更新
一个想法 - 因为我有is_enqueue_enabled,也许它正在存储所有消息,直到它可以处理所有消息?如果是这样,我可以安全地关闭它吗?
CREATE PROCEDURE [dbo].[Parse_EN_Messages]
AS
--mdb 2012/09/05 version 1.2
-- With apologies and thanks to Remus Rusanu, Jonathon Kehayias, Mladen Prajdic, and Jasper Smith for writing
-- about EN, answering questions, and getting the word out about this awesome feature of SQL Server 2005+.
-- Also thanks to Mikael …Run Code Online (Sandbox Code Playgroud) 我编写了一个带有 SQL Server 后端的应用程序,用于收集和存储大量记录。我已经计算出,在高峰期,平均记录量大约为每天 3-40 亿条(运行 20 小时)。
我最初的解决方案(在我完成数据的实际计算之前)是让我的应用程序将记录插入到我的客户查询的同一个表中。显然,这会很快崩溃并烧毁,因为不可能查询插入了这么多记录的表。
我的第二个解决方案是使用 2 个数据库,一个用于应用程序接收的数据,另一个用于客户端就绪数据。
我的应用程序将接收数据,将其分成大约 10 万条记录的批次,然后批量插入到临时表中。在大约 100k 条记录之后,应用程序将使用与之前相同的架构即时创建另一个临时表,并开始插入到该表中。它将在具有 10 万条记录的作业表中创建一条记录,并且 SQL Server 端的存储过程会将数据从临时表移动到客户端就绪的生产表,然后删除我的应用程序创建的表临时表。
除了具有作业表的临时数据库外,两个数据库都具有相同的 5 个表集,具有相同的架构。临时数据库在大量记录将驻留的表上没有完整性约束、键、索引等。如下所示,表名是SignalValues_staging. 目标是让我的应用程序尽快将数据发送到 SQL Server。动态创建表以便轻松迁移的工作流程非常有效。
以下是我的临时数据库中的 5 个相关表,以及我的工作表:
我编写的存储过程处理从所有临时表中移动数据并将其插入到生产中。下面是我的存储过程的一部分,它从临时表插入到生产中:
-- Signalvalues jobs table.
SELECT *
,ROW_NUMBER() OVER (ORDER BY JobId) AS 'RowIndex'
INTO #JobsToProcess
FROM
(
SELECT JobId
,ProcessingComplete
,SignalValueStagingTableName AS 'TableName'
,(DATEDIFF(SECOND, (SELECT last_user_update
FROM sys.dm_db_index_usage_stats
WHERE database_id = DB_ID(DB_NAME())
AND OBJECT_ID = OBJECT_ID(SignalValueStagingTableName))
,GETUTCDATE())) SecondsSinceLastUpdate
FROM SignalValueJobs
) cte
WHERE cte.ProcessingComplete = 1 …Run Code Online (Sandbox Code Playgroud) 我只是在摆弄 SSMS 图形界面并研究“恢复”任务的选项。
我注意到的一件事是,当我单击“生成脚本”时,查询的第一行是:
RESTORE DATABASE [MyDatabase] FROM DISK = N'Server_Patch\Database_name_LOGSHIPPING.BKP' WITH FILE = 1, NORECOVERY, NOUNLOAD, STATS = 5 ( and a lot of log backups for point in time )
Run Code Online (Sandbox Code Playgroud)
好的,没问题,但是,我每天都在备份这个数据库。这Database_name_LOGSHIPPING.BKP是我一个月前为日志传送制作的文件的名称。
为什么当我尝试使用 SSMS 图形界面恢复备份时,它指向这个备份文件?我什至没有这个文件了。
通过 MSSQLTIPS 的这个查询,我可以看到这个数据库的所有备份:
SELECT
CONVERT(CHAR(100), SERVERPROPERTY('Servername')) AS Server,
msdb.dbo.backupset.database_name,
msdb.dbo.backupset.backup_start_date,
msdb.dbo.backupset.backup_finish_date,
msdb.dbo.backupset.expiration_date,
CASE msdb..backupset.type
WHEN 'D' THEN 'Database'
WHEN 'L' THEN 'Log'
END AS backup_type,
msdb.dbo.backupset.backup_size,
msdb.dbo.backupmediafamily.logical_device_name,
msdb.dbo.backupmediafamily.physical_device_name,
msdb.dbo.backupset.name AS backupset_name,
msdb.dbo.backupset.description
FROM msdb.dbo.backupmediafamily
INNER JOIN msdb.dbo.backupset ON msdb.dbo.backupmediafamily.media_set_id = msdb.dbo.backupset.media_set_id
WHERE …Run Code Online (Sandbox Code Playgroud) 在分析数据库时,我遇到了一个视图,该视图引用了一些非确定性函数,对于此应用程序池中的每个连接,这些函数每分钟被访问1000-2500 次。一个简单的视图产生以下执行计划:SELECT
对于少于一千行且每隔几个月可能会看到一两行更改的视图来说,这似乎是一个复杂的计划。但以下其他注意事项会变得更糟:
UDFs 来构建字符串UDFs 以获取本地化语言的 ISO 代码UDF作为JOIN谓词INSERT/ UPDATE/DELETE在每个触发器来写入底层表CURSORS该EXEC存储过程作为参考更多的这些串建设UDF秒。这对我来说似乎很糟糕,但我只有几年的 TSQL 经验。也越来越好!
看来开发人员认为这是一个好主意,这样做是为了让存储的几百个字符串可以根据从UDF特定于模式的a 返回的字符串进行翻译。
这是堆栈中的一个视图,但它们都同样糟糕:
CREATE VIEW [UserWKStringI18N]
AS
SELECT b.WKType, b.WKIndex
, CASE
WHEN ISNULL(il.I18NID, N'') = N''
THEN id.I18NString
ELSE il.I18nString
END AS WKString
,CASE
WHEN ISNULL(il.I18NID, N'') …Run Code Online (Sandbox Code Playgroud) performance sql-server sql-server-2008-r2 view functions query-performance
这是一个我似乎无法找到答案的简单问题。
在性能方面,如果我有一个WHERE条款,例如a=0 and b=0 and ... z=0,如果我用 替换该条件,我会获得任何性能a+b+...+z=0吗?
换句话说,通过替换以下内容是否有任何性能提升
Select *
From MyTable
Where A=0 and B=0 and C=0 and D=0...
Run Code Online (Sandbox Code Playgroud)
和
Select *
From MyTable
Where A+B+C+D=0...
Run Code Online (Sandbox Code Playgroud)
我知道它可以依赖于索引,但为此目的,我们只说不存在索引。算术运算符 (+) 的性能是否比“OR”或“AND”逻辑运算符更好?
我的印象是加法比使用 AND 或 OR 的多个条件表现得更好。
在 420 万行的表上
返回行其中 A=0 B=0 和 C=0 -> 351748 行
添加 (A+B+C=0) 需要 5 秒,而逻辑条件 A=0 和 B=0 和 C=0 需要 11 秒。
返回行 其中 A<>0 B<>0 或 C<>0 -> 3829750 行 58 秒
返回行 …
我的数据库中有 2 个表。
表格1
-------------------------------------------------------------------------
| name | family | phone | email | gender | phone2 | address | birthdate |
-------------------------------------------------------------------------
Run Code Online (Sandbox Code Playgroud)
表#2
-----------------------------------------
| gender | address | phone | birthdate |
-----------------------------------------
Run Code Online (Sandbox Code Playgroud)
在表#1的列地址和PHONE2是空的和列性别和生日的值是相同的表#2。
当每行的性别和出生日期相同时,如何从表 #2 中读取数据并使用表 #2 address和phone列中的值更新表 #1 中的address和phone2?
例如:这是表 #1 中的一些数据
-------------------------------------------------------------------------
| name | family | phone | email | gender | phone2 | address …Run Code Online (Sandbox Code Playgroud) sql-server ×10
performance ×4
restore ×2
filestream ×1
functions ×1
join ×1
optimization ×1
t-sql ×1
update ×1
view ×1