小编孔夫子*_*孔夫子的帖子

对于绝对性能,SUM 更快还是 COUNT?

这与计算符合特定条件的记录数有关,例如invoice amount > $100

我倾向于更喜欢

COUNT(CASE WHEN invoice_amount > 100 THEN 1 END)
Run Code Online (Sandbox Code Playgroud)

然而,这同样有效

SUM(CASE WHEN invoice_amount > 100 THEN 1 ELSE 0 END)
Run Code Online (Sandbox Code Playgroud)

我认为 COUNT 更可取有两个原因:

  1. 传达意图,即 COUNT
  2. COUNT 可能i += 1某处涉及一个简单的操作,而 SUM 不能指望它的表达式是一个简单的整数值。

有没有人有关于特定 RDBMS 差异的具体事实?

mysql postgresql sqlite oracle sql-server

36
推荐指数
2
解决办法
4万
查看次数

为什么 DELETE 会对性能产生挥之不去的影响?

最后是一个测试脚本,用于比较@table 变量和#temp 表之间的性能。我想我已经正确设置了 - 性能计时是在 DELETE/TRUNCATE 命令之外进行的。我得到的结果如下(以毫秒为单位)。

@Table Variable  #Temp (delete)  #Temp (truncate)
---------------  --------------  ----------------
5723             5180            5506
15636            14746           7800
14506            14300           5583
14030            15460           5386
16706            16186           5360
Run Code Online (Sandbox Code Playgroud)

只是为了确保我是理智的,这表明 CURRENT_TIMESTAMP (aka GetDate()) 是在语句时使用的,而不是批处理时,因此 TRUNCATE/DELETE 与SET @StartTime = CURRENT_TIMESTAMP语句之间不应有交互。

select current_timestamp
waitfor delay '00:00:04'
select current_timestamp

-----------------------
2012-10-21 11:29:20.290

-----------------------
2012-10-21 11:29:24.290
Run Code Online (Sandbox Code Playgroud)

当使用 DELETE 清除表时,第一次运行和后续运行之间的跳转非常一致。我对DELETE 的理解缺少什么?我已经重复了很多次,交换了顺序,调整了 tempdb 的大小以使其不需要增长等。

CREATE TABLE #values (
  id int identity primary key, -- will be clustered …
Run Code Online (Sandbox Code Playgroud)

performance sql-server delete truncate sql-server-2012

20
推荐指数
1
解决办法
4094
查看次数

创建一个计划指南来缓存(懒惰假脱机)CTE 结果

我通常通过首先构造一个使用正确计划的查询,然后将其复制到类似的查询中来创建计划指南。但是,这有时很棘手,尤其是在查询不完全相同的情况下。从头开始创建计划指南的正确方法是什么?

SQLKiwi 已经提到在 SSIS 中制定计划,有没有一种方法或有用的工具来帮助为 SQL Server 制定一个好的计划?

有问题的具体实例是这个 CTE:SQLFiddle

with cte(guid,other) as (
  select newid(),1 union all
  select newid(),2 union all
  select newid(),3)
select a.guid, a.other, b.guid guidb, b.other otherb
from cte a
cross join cte b
order by a.other, b.other;
Run Code Online (Sandbox Code Playgroud)

有没有任何方法来使结果拿出正好3个不同的guidS和没有更多?我希望将来能够通过包含多次引用的 CTE 类型查询的计划指南来更好地回答问题,以克服一些 SQL Server CTE 怪癖。

sql-server cte t-sql

19
推荐指数
1
解决办法
2882
查看次数

为什么一定要从双表中选择?

这适用于最有可能出现在 StackOverflow/dba.stackexchange 上的主要关系数据库管理系统,包括SQL Server、MySQL、PostgreSQL 和 SQLite (WebSQL)

select 'abc' abc, 1 def;
Run Code Online (Sandbox Code Playgroud)

它不适用于 Oracle。为什么我们需要在Oracle中选择DUAL?SQL 的 ISO/ANSI 标准是否要求SELECT语句的 FROM 子句?


编辑:

根据Bacon Bit的回答,它似乎是 SQL 标准所要求的。

所以实际上,因为名称 DUAL 用词不当,如果我要创建一个表并将其命名为 ATOM 或 ONE,例如create table one (atom int);.. select 'abc' abc, 1 def FROM one;- 与 相比是否有性能损失SELECT .. FROM DUAL

oracle select

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

用于“已归档但可用”数据的 SQL Server 数据库设计

我们有这个打算“缩小”的大型数据库(> 1TB)。数据库围绕一个主要实体,我们称之为“访问”。为了讨论,假设它是一个医疗实践的数据库。

共有30个访问“类型”,例如程序、年度、随访、免疫等,每个访问“类型”都是“访问”的子表,例如“visit_immuno”。

该数据库自 2000 年以来已经积累了大约 12 年的数据。有人建议我们将大约 3 年的数据保留在“实时”版本中,而将其余的数据保留在“旧数据”数据库中。日期仅存储在“访问”表中,因为它是标准化的。Visit 表还包含一个ROWVERSION列和一个BIGINT伪标识(集群)列。出于所有意图和目的,假设集群键由 SEQUENCE (SQL Server 2012 Enterprise) 填充 - 我们将其命名为cid

visit.date当医生的推移延长探视,并与他的数据的“公文包”的回报并不总是以相同的顺序作为聚集键,例如,它被合并到主表。“访问”表也有一些更新,这将导致ROWVERSION列与ciddate列不同步- 简单地说,由于这个原因,ROWVERSIONcid不会制作合适的分区键。

从“实时”中删除数据的业务规则是visit.date必须大于 36 个月并且visit_payment必须存在子记录。此外,“old_data”数据库不包含任何基表,除了visit%.

所以我们最终得到:

直播DB(日常使用) -所有表老数据DB -对于较旧的数据visit%

该提案要求一个组合数据库,它是一个外壳,其中包含(除外)中所有基表的同义词以及跨两个数据库中的表联合所有的视图Live DBvisit%visit%

假设在Old-Data数据库中创建了相同的索引,查询会在 UNION-ALL视图上表现良好吗?什么类型的查询模式可能会影响 UNION-ALL视图的执行计划?

database-design sql-server sql-server-2012

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

SQL Server 数据压缩绝对适用于只读数据库吗?

我读过的一些关于 SQL Server 数据压缩的文献指出,写入成本增加到通常所需的四倍左右。这似乎也暗示这是数据压缩的主要缺点,强烈暗示对于只读存档数据库,性能将(除了少数例外)通过使用 100% 填充页面的数据压缩来提高。

  1. 以上说法是否属实?
  2. 数据压缩和其他方式之间的主要“变化”是什么(用于阅读)

    • “CPU + x%”?
    • “IO -y%”?
    • 页面拆分发生?
    • tempdb 用法?
    • 内存使用情况?
  3. 和写作?

出于此问题的目的,您可以将上下文限制为大型(> 1TB)数据库的PAGE 级压缩,但始终欢迎其他评论。


参考:

SQL Server 存储引擎博客(DW 场景显示压缩非常有利)
数据压缩:策略、容量规划和最佳实践

决定压缩内容的更详细方法涉及分析每个表和索引的工作负载特征。它基于以下两个指标:

U:特定表、索引或分区上的更新操作相对于该对象上的总操作的百分比。U 的值越低(即表、索引或分区不经常更新),它就越适合进行页面压缩。
S:表、索引或分区上的扫描操作相对于该对象上的总操作的百分比。S 的值越高(即表、索引或分区被扫描的次数越多),它就越适合进行页面压缩。

以上两者显然都偏向于推荐 DW 样式数据库(读取密集型/独占性、大数据操作)的页面压缩。

data-warehouse sql-server compression sql-server-2012

11
推荐指数
1
解决办法
4645
查看次数

SQL Server 是如何生成加起来达到 6,000% 的查询执行计划的?

奇怪的执行计划

今天我在 The Heap 上,正在查看我认为可以改进的查询计划。然而,它创造了一些东西,动摇了我对 SQL Server 查询优化器的信念。如果甚至不能计数到 100%,我还可以信任它吗?

表的特点:

  • 聚集在非标识列上
  • 12 个索引,其中之一是相关date_entered
  • 60,000 条记录
  • 26列不同类型和长度
  • PAGE 压缩表

有没有人以前见过这个,是什么导致计划看起来如此扭曲?


以下来自 SQL Sentry Plan Explorer

SQL Sentry 计划资源管理器 - 图像 顶级运营

sql-server optimization ssms execution-plan sql-server-2012

11
推荐指数
1
解决办法
3153
查看次数

SQL ANSI JOIN 优先级

我有一个看起来像这样的查询:

    SELECT *
      FROM TBLA A
 LEFT JOIN TBLB B ON A.Col1 = B.Col2
RIGHT JOIN TBLC C ON B.Col3 = C.Col4
      JOIN TBLD D ON C.Col5 = D.Col6
Run Code Online (Sandbox Code Playgroud)

将按照什么顺序解析连接?我对 SQL Server 最感兴趣,并将对它的解释标记为答案,但我对 ANSI/ISO 标准及其在各种 RDBMS 中的工作方式同样感兴趣。

这个问题的原因是为了弄清楚为什么结果与这个查询不同

    SELECT *
      FROM TBLA A
CROSS JOIN TBLC C
 LEFT JOIN TBLB B ON A.Col1 = B.Col2 AND B.Col3 = C.Col4
      JOIN TBLD D ON C.Col5 = D.Col6
Run Code Online (Sandbox Code Playgroud)

mysql postgresql oracle join sql-server

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

是否有更简洁的方法将 UTC 日期时间仅转换为本地日期?

我正在尝试编写一个查询,该查询仅根据 UTC 日期时间字段的本地日期部分对记录进行分组。

例如,如果我的表包含10/19/2012 2:00:00,那么它应该被分组为10/18/2012,因为我的本地时间是美国东部时间 (-5h) 并且我只对字段的日期部分感兴趣。

我知道我DateAdd(day, DateDiff(day, 0, MyDate), 0)只能从日期时间字段中获取日期部分,我可以DateAdd(minute, DateDiff(minute, GetUtcDate(), GetDate()), MyUtcDate)用来将 UTC 日期时间转换为本地日期时间。

但是将两者结合起来严重冒犯了我。

在 SQL Server 2005 中,是否有比这更好的方法来获取 UTC 日期时间字段的日期部分,转换为本地时间?

  SELECT DateAdd(day, DateDiff(day, 0, DateAdd(minute, DateDiff(minute, GetUtcDate(), GetDate()), MyUtcDate)), 0)
       , Count(*)
    FROM MyTable
GROUP BY DateAdd(day, DateDiff(day, 0, DateAdd(minute, DateDiff(minute, GetUtcDate(), GetDate()), MyUtcDate)), 0)
Run Code Online (Sandbox Code Playgroud)

sql-server-2005 sql-server query-refactor

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

为什么 SQL Server 不优化 UNION?

考虑这些查询(SQL Fiddle):

查询 1:

SELECT * INTO #TMP1 FROM Foo
UNION
SELECT * FROM Boo
UNION
SELECT * FROM Koo;
Run Code Online (Sandbox Code Playgroud)

查询 2:

SELECT * INTO #TMP2 FROM Foo
UNION
SELECT * FROM Boo
UNION ALL
SELECT * FROM Koo;
Run Code Online (Sandbox Code Playgroud)

请注意,Koo 与 Boo/Foo 不重叠,因此最终结果是相同的。问题是为什么第一个UNION / UNION组合没有合并成单个 SORT 操作?

performance sql-server optimization union query-performance

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