小编Hau*_*uri的帖子

表分区能提高性能吗?这值得么?

我刚刚参与了一个项目,我必须在该项目上开发一个数据迁移过程和一个使用现有 SQL Server 数据库的 Web 界面。这个数据库是几年前由另一个人开发的,它有大约 100 GB 的数据,并且每 10 分钟增加一次(它存储来自多个单元的 10 分钟数据 -> 每个设备每天 144 条记录)。几个表有大约 1000 万行。关键是我认为主表的设计方式不是最有效或最适合通常执行的查询类型的方式。现在我需要证明我所说的是否比已经实施的更好。DB 表的数量很庞大,但可以通过下图简化结构: 在此处输入图片说明

Date_Id 字段由使用 DateTime 字段的函数自动生成。两个表中都有两个索引。每个表的簇索引包含相同顺序的 PK 字段。Unit 表的第二个索引仅包含 Unit_Id 字段,而 UnitData 中的第二个索引按此顺序包含 Unit_Id 和 DateTime 字段。

但是,我认为设计应该是这样的: 在此处输入图片说明

在这种情况下,只需要 PK 字段的聚集索引。对于此数据库设计,通常的查询类似于:

SELECT ud.*
FROM Unit u, UnitData ud
WHERE u.Unit_Id = ud.Unit_Id and ud.DateTime >= 'dd-MM-yyyy'
ORDER BY ud.Unit_Id, ud.DateTime
Run Code Online (Sandbox Code Playgroud)

现在出现了我真的不明白的事情:有人告诉我,拥有 Date_Id 列的唯一原因是将其用作该表的分区列。我问过对这个表进行分区的真正必要性,答案是“在需要每日或每月数据时更有效地运行查询”。在此之前我不太了解分区,所以我检查了这些链接:

http://msdn.microsoft.com/en-us/library/ms190787.aspx

表分区有何帮助?

通过分区提高性能

考虑到理想的查询是按设备和日期时间过滤,问题是:

  1. 您认为第一个数据库设计(带分区)的最有效和最理想的查询是什么?
  2. 您真的认为针对第一个数据库设计的最有效查询比第二个(我上面写的那个)更好吗?
  3. 如果前一个是肯定的,您真的认为有两个额外字段(Id 和 Date-Id)和一个额外索引的改进值得吗?

非常感谢!!

performance sql-server partitioning query-performance

7
推荐指数
1
解决办法
4万
查看次数

获取负责查询的用户名和/或 IP 地址

我使用以下查询来查找查询中的性能改进:

SELECT TOP 20 SUBSTRING(qt.text, (qs.statement_start_offset/2)+1, 
        ((CASE qs.statement_end_offset
          WHEN -1 THEN DATALENGTH(qt.text)
         ELSE qs.statement_end_offset
         END - qs.statement_start_offset)/2)+1),
  qs.execution_count,
  qs.total_logical_reads, qs.last_logical_reads, qs.min_logical_reads,
  qs.max_logical_reads, qs.total_physical_reads, qs.last_physical_reads,
  qs.min_physical_reads, qs.max_physical_reads,
  qs.total_elapsed_time / 1000000 As total_elapsed_time, 
  qs.last_elapsed_time / 1000000 As last_elapsed_time,
  qs.min_elapsed_time / 1000000 As min_elapsed_time, 
  qs.max_elapsed_time / 1000000 As max_elapsed_time,
  qs.last_execution_time, qs.creation_time, qp.query_plan
FROM sys.dm_exec_query_stats qs
CROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) qt
CROSS APPLY sys.dm_exec_query_plan(qs.plan_handle) qp
WHERE qt.encrypted=0
AND last_execution_time >= DATEADD (MINUTE , -5 , CURRENT_TIMESTAMP )
ORDER BY qs.total_logical_reads DESC
--ORDER BY qs.total_physical_reads DESC …
Run Code Online (Sandbox Code Playgroud)

performance sql-server users query-performance performance-tuning

6
推荐指数
2
解决办法
3万
查看次数

索引几乎相同的逻辑读取量差异

我试图弄清楚为什么在 SQL Server 中,两个相同的查询在两个几乎相同的索引下执行时花费的时间略有不同。提到的查询非常简单,具有以下形状>

set statistics io on
set statistics time on

SELECT t.field3
FROM Table t --WITH(INDEX(Index2))
WHERE t.field1 = 6 AND t.field2 = 'B' 
AND t.field3 >= CAST ('01-07-2012' As DateTime) AND t.field3 < CAST ('01-10-2012' As DateTime)
ORDER BY t.field3
Run Code Online (Sandbox Code Playgroud)

如果我在 Table t(包含 52M 行)上运行此查询,则检索到的统计信息为:

  • 逻辑读数:95
  • CPU时间:15毫秒
  • 经过时间:6 ms

如果我检查查询的实际执行计划,它会在 Index1 上显示 100% 的 Index Seek,它是非聚集的,并按此顺序包含字段 field1、field2、field3。但是,如果我取消注释强制使用 Index2 的行,它包含相同顺序的相同字段,但它是聚集的(主键),统计信息是:

  • 逻辑读取:1456
  • CPU时间:15毫秒
  • 已用时间:12 毫秒

虽然花费的总时间并没有特别糟糕,但我想了解这里发生了什么。谁能给我一个解释?除了时差很小之外,还有性能差异吗?

非常感谢 !!

performance sql-server query-performance

5
推荐指数
1
解决办法
888
查看次数

查询看起来最佳,但逻辑读取量很大

我在 SQL Server 中运行以下(非常简单)查询:

    SELECT MAX(PK_Field1)
    FROM MainTable kh
    WHERE kh.PK_Field1 >= '2014-12-01T00:00:00'
    AND kh.PK_Field2 = 1572
    AND kh.PK_Field3= 'FD5BF2F3-8ED7-479C-A71F-D04E4288CBFC'
Run Code Online (Sandbox Code Playgroud)

我从中得到了这些统计数据:

Table 'MainTable'. Scan count 9, logical reads 31078, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

 SQL Server Execution Times:
   CPU time = 171 ms,  elapsed time = 44 ms.
Run Code Online (Sandbox Code Playgroud)

虽然经过的时间并不多,但这个查询每十分钟执行大约一千次,所以超过 30k 的逻辑读取对我来说似乎不是很理想。但是,该表中的主索引的设计方式使这样的查询可以充分利用它。表 MainTable 包含以下内容:

PK_Field1 datetime
PK_Field2 int
PK_Field3 uniqueidentifier
Another_Field datetime
Run Code Online (Sandbox Code Playgroud)

该表不包含其他列,它有 300 万条记录,唯一的索引是 PK 字段上的聚集索引(与表中定义的顺序相同,按 ASC …

performance sql-server optimization query-performance

5
推荐指数
1
解决办法
1331
查看次数

了解 SQL Server 中的日期时间格式

我已经处理了很长时间的 MS SQL Server 日期时间类型,但从未想过为什么会发生以下情况:

  1. 我查询一个包含 smalldatetime 列的表。这个 smalldatetime 总是以格式返回yyyy-MM-dd hh:mm:ss
  2. 现在我写了一个不同的查询,我想在 WHERE 子句中应用一个 smalldatetime 过滤器,比如 WHERE TimeStamp >= 'yyyy-MM-dd hh:mm:ss'
  3. SQL Server 检索到错误并告诉我无法将该 nvarchar 转换为有效的 smalldatetime

似乎只有当我更改指定的格式并使用欧洲格式编写它时才有效,例如WHERE TimeStamp >= 'dd-MM-yyyy hh:mm:ss'. 为什么 SQL Server 以一种在应用于自身时不可覆盖或有效的格式向我显示日期?我在编写查询时更改日期格式没有任何问题,但我想在应用程序级别(Java-JDBC 应用程序)使用这些日期,并且我不想一直应用日期格式更改。 .. 谁能解释一下为什么会发生这种情况,以及是否有任何方法可以在数据库级别解决它?谢谢!!

编辑:请参阅下面 Management Studio 中错误的屏幕截图。 在此处输入图片说明

sql-server date-format datetime

3
推荐指数
2
解决办法
5万
查看次数

优化 SQL Server 中的简单查询

这应该是一个非常简单的查询,但老实说,我认为它的执行时间可以改进。

select idTag,MAX(pctimestamp) AS PCTIMESTAMP,getdate() AS NOW, datediff(SECOND,MAX(pctimestamp),getdate()) AS DELAY 
from ValuesTagsOPC
group by IdTag
Run Code Online (Sandbox Code Playgroud)

此查询从“ValuesTagsOPC”表返回 1386 行,该表包含大约 4000 万行,并具有以下结构,由创建脚本检索:

CREATE TABLE [dbo].[ValuesTagsOPC](
    [IdTag] [int] NOT NULL,
    [TTimeStamp] [datetime] NOT NULL,
    [PCTimeStamp] [datetime] NOT NULL,
    [Value] [nvarchar](50) NOT NULL,
    [Quality] [int] NOT NULL,
 CONSTRAINT [PK_ValuesTagsOPC] PRIMARY KEY CLUSTERED 
(
    [IdTag] ASC,
    [PCTimeStamp] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]
Run Code Online (Sandbox Code Playgroud)

很明显,它的主键上有一个聚集索引。SQL Server 的时间和 IO 统计信息如下(抱歉,它是西班牙语):

(1386 …
Run Code Online (Sandbox Code Playgroud)

performance sql-server query-performance

2
推荐指数
1
解决办法
357
查看次数