小编m__*_*m__的帖子

主键中指定的排序顺序,但排序是在 SELECT 上执行的

我将传感器数据存储在表SensorValues 中。表和主键如下:

CREATE TABLE [dbo].[SensorValues](
  [DeviceId] [int] NOT NULL,
  [SensorId] [int] NOT NULL,
  [SensorValue] [int] NOT NULL,
  [Date] [int] NOT NULL,
CONSTRAINT [PK_SensorValues] PRIMARY KEY CLUSTERED 
(
  [DeviceId] ASC,
  [SensorId] ASC,
  [Date] DESC
) WITH (
    FILLFACTOR=75,
    DATA_COMPRESSION = PAGE,
    PAD_INDEX = OFF,
    STATISTICS_NORECOMPUTE = OFF,
    SORT_IN_TEMPDB = OFF,
    IGNORE_DUP_KEY = OFF,
    ONLINE = OFF,
    ALLOW_ROW_LOCKS = ON,
    ALLOW_PAGE_LOCKS = ON)
  ON [MyPartitioningScheme]([Date])
Run Code Online (Sandbox Code Playgroud)

然而,当我选择在特定时间有效的传感器值时,执行计划告诉我它正在执行排序。这是为什么?

我原以为,由于我存储了按日期列排序的值,因此不会发生排序。还是因为索引不仅仅按日期列排序,即它不能假设结果集已排序?

SELECT TOP 1 SensorValue
  FROM SensorValues
  WHERE SensorId = 53
    AND DeviceId = …
Run Code Online (Sandbox Code Playgroud)

sql-server primary-key

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

存储顺序与结果顺序

这是主键中指定的排序顺序的衍生问题,但排序是在 SELECT 上执行的

@Catcall关于存储顺序(聚集索引)和输出顺序的主题

很多人认为聚集索引可以保证输出的排序顺序。但这不是它的作用。它保证了磁盘上的存储顺序。 例如,请参阅此博客文章

我已经阅读了 Hugo Kornelis 的博客文章,并了解到索引并不能保证 sql server 以特定顺序读取记录。然而,我很难接受我不能为我的场景假设这一点?

CREATE TABLE [dbo].[SensorValues](
  [DeviceId] [int] NOT NULL,
  [SensorId] [int] NOT NULL,
  [SensorValue] [int] NOT NULL,
  [Date] [int] NOT NULL,
CONSTRAINT [PK_SensorValues] PRIMARY KEY CLUSTERED 
(
  [DeviceId] ASC,
  [SensorId] ASC,
  [Date] DESC
) WITH (
    FILLFACTOR=75,
    DATA_COMPRESSION = PAGE,
    PAD_INDEX = OFF,
    STATISTICS_NORECOMPUTE = OFF,
    SORT_IN_TEMPDB = OFF,
    IGNORE_DUP_KEY = OFF,
    ONLINE = OFF,
    ALLOW_ROW_LOCKS = ON,
    ALLOW_PAGE_LOCKS = ON)
  ON …
Run Code Online (Sandbox Code Playgroud)

sql-server clustered-index execution-plan sorting

8
推荐指数
1
解决办法
4773
查看次数

从大表中按日期选择每第 n 个值

为了清楚起见,在 2012-06-20 重写了这个问题,检查旧版本的编辑

背景和问题

我为某些设备上的几个传感器收集数据。我想在图形中以曲线的形式为用户显示这些数据,即我想绘制测量点并在它们之间画线。用户可以通过在图表中缩放和平移来决定他想要显示值的日期范围。

测量值的数量开始增加,此时我有许多值在500'000'000范围内,并且还在计数。对于单个传感器,到目前为止,我最多可以找到大约2'000'000 个值,但它很可能会增加。这些值不是以均匀间隔(即每秒)记录的,而是在可以测量更改时记录的(请参阅下面日期列中的差异)。

Date  SensorValue
----- -----------
10    123
30    118
70    114
85    115
90    116
95    117
Run Code Online (Sandbox Code Playgroud)

由于此图形的显示区域为1000 像素,因此获取所有这些值毫无意义。相反,我尝试获取最多1000 个值,并将它们均匀分布在用户放大的日期范围内。确切地返回日期范围内的哪些值并不重要,只要它们在日期方面均匀分布(记住这一点很重要,因为它们不是以均匀间隔记录的)。

我将这些值存储在一个非常简单的表中,如下所示,只有一个(聚集)索引。请注意,Date存储为整数(“unix 时间”)而不是datetime2字段。该表按Date是否重要进行分区。

CREATE TABLE [dbo].[SensorValues](
  [DeviceId] [int] NOT NULL,
  [SensorId] [int] NOT NULL,
  [SensorValue] [int] NOT NULL,
  [Date] [int] NOT NULL,
CONSTRAINT [PK_SensorValues] PRIMARY KEY CLUSTERED 
(
  [DeviceId] ASC,
  [SensorId] ASC,
  [Date] DESC
);
Run Code Online (Sandbox Code Playgroud)

我正在寻找两件事之一,要么是一个改进的查询,它可以更快地返回这些值,要么 …

sql-server sql-server-2012

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

在一个查询中选择多个传感器值

背景

我有几个设备,每个设备都有几个传感器。我不时地记录这些并将它们存储在下面描述的表中。当有人请求一个网页时,我会一个接一个地获取这些值中的几个(最新记录的)并将它们显示给用户。但是目前这需要很长时间,因为需要提取的值太多,每个值的提取需要大约 8 毫秒,并且我们总共讨论了大约 300 毫秒的总页面加载时间增加 - 对于一个相对较好的页面。

CREATE TABLE [dbo].[SensorValues](
  [DeviceId] [int] NOT NULL,
  [SensorId] [int] NOT NULL,
  [SensorValue] [int] NOT NULL,
  [Date] [int] NOT NULL, --- stored as unixtime
CONSTRAINT [PK_SensorValues] PRIMARY KEY CLUSTERED 
(
  [DeviceId] ASC,
  [SensorId] ASC,
  [Date] DESC
);
Run Code Online (Sandbox Code Playgroud)

该表在日期列上每周进行分区。

我现在应该做什么

所以,我做的是以下。我选择每个分区中当前日期/时间之前的最大值。并选出最大的值。

SELECT TOP (1) ca.SensorValue, ca.Date
  FROM sys.partitions AS p
  CROSS APPLY
  (
  SELECT TOP (1) v.Date, v.SensorValue
    FROM SensorValue AS v
    WHERE $PARTITION.SensorValues_Date_PF(v.Date) = p.[partition_number]
    AND v.DeviceId = @fDeviceId
    AND v.SensorId = @fSensorId …
Run Code Online (Sandbox Code Playgroud)

sql-server partitioning select sql-server-2012 group-by

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

外键对性能的影响有多大?

我正在检查一个 SQL Server 2008R2 安装有很大的性能问题。目前我正在查看它的索引和外键,发现没有一个表指定了任何外键。要么应用程序自己处理所有业务逻辑,要么安装错误。

外键对性能的影响有多大?还是它们只存在于业务逻辑?是否有没有外键是优势的情况?(例如本系统支持 SQL Server、Oracle 和 DB2。)

performance foreign-key sql-server-2008-r2

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

缩小旧分区

我有一个大的分区时间序列表,其中每个分区都存储在它自己的文件中。由于它是基于时间序列的分区按周划分,而且我只存储新数据,因此我一次积极写入的分区不超过 2 个。我在索引上将 FILLFACTOR 设置为 75,因为数据是随机输入的。

旧的数据分区占用了相当多的空间,仅使用了大约 60-70% 的空间。是否可以自动更改所述分区上的 FILLFACTOR,重建索引并缩小文件?由于我不再写入这些分区,因此它们的大小不应再增长。

sql-server shrink partitioning sql-server-2012 fill-factor

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