这与计算符合特定条件的记录数有关,例如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 更可取有两个原因:
COUNT
COUNT
可能在i += 1
某处涉及一个简单的操作,而 SUM 不能指望它的表达式是一个简单的整数值。有没有人有关于特定 RDBMS 差异的具体事实?
最后是一个测试脚本,用于比较@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) 我通常通过首先构造一个使用正确计划的查询,然后将其复制到类似的查询中来创建计划指南。但是,这有时很棘手,尤其是在查询不完全相同的情况下。从头开始创建计划指南的正确方法是什么?
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个不同的guid
S和没有更多?我希望将来能够通过包含多次引用的 CTE 类型查询的计划指南来更好地回答问题,以克服一些 SQL Server CTE 怪癖。
这适用于最有可能出现在 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
?
我们有这个打算“缩小”的大型数据库(> 1TB)。数据库围绕一个主要实体,我们称之为“访问”。为了讨论,假设它是一个医疗实践的数据库。
共有30个访问“类型”,例如程序、年度、随访、免疫等,每个访问“类型”都是“访问”的子表,例如“visit_immuno”。
该数据库自 2000 年以来已经积累了大约 12 年的数据。有人建议我们将大约 3 年的数据保留在“实时”版本中,而将其余的数据保留在“旧数据”数据库中。日期仅存储在“访问”表中,因为它是标准化的。Visit 表还包含一个ROWVERSION
列和一个BIGINT
伪标识(集群)列。出于所有意图和目的,假设集群键由 SEQUENCE (SQL Server 2012 Enterprise) 填充 - 我们将其命名为cid
。
在visit.date
当医生的推移延长探视,并与他的数据的“公文包”的回报并不总是以相同的顺序作为聚集键,例如,它被合并到主表。“访问”表也有一些更新,这将导致ROWVERSION
列与cid
和date
列不同步- 简单地说,由于这个原因,ROWVERSION
也cid
不会制作合适的分区键。
从“实时”中删除数据的业务规则是visit.date
必须大于 36 个月并且visit_payment
必须存在子记录。此外,“old_data”数据库不包含任何基表,除了visit%
.
所以我们最终得到:
直播DB(日常使用) -所有表老数据DB -对于较旧的数据visit%
表
该提案要求一个组合数据库,它是一个外壳,其中包含(除外)中所有基表的同义词以及跨两个数据库中的表联合所有的视图。Live DB
visit%
visit%
假设在Old-Data
数据库中创建了相同的索引,查询会在 UNION-ALL视图上表现良好吗?什么类型的查询模式可能会影响 UNION-ALL视图的执行计划?
我读过的一些关于 SQL Server 数据压缩的文献指出,写入成本增加到通常所需的四倍左右。这似乎也暗示这是数据压缩的主要缺点,强烈暗示对于只读存档数据库,性能将(除了少数例外)通过使用 100% 填充页面的数据压缩来提高。
数据压缩和其他方式之间的主要“变化”是什么(用于阅读)
出于此问题的目的,您可以将上下文限制为大型(> 1TB)数据库的PAGE 级压缩,但始终欢迎其他评论。
参考:
SQL Server 存储引擎博客(DW 场景显示压缩非常有利)
数据压缩:策略、容量规划和最佳实践
决定压缩内容的更详细方法涉及分析每个表和索引的工作负载特征。它基于以下两个指标:
U:特定表、索引或分区上的更新操作相对于该对象上的总操作的百分比。U 的值越低(即表、索引或分区不经常更新),它就越适合进行页面压缩。
S:表、索引或分区上的扫描操作相对于该对象上的总操作的百分比。S 的值越高(即表、索引或分区被扫描的次数越多),它就越适合进行页面压缩。
以上两者显然都偏向于推荐 DW 样式数据库(读取密集型/独占性、大数据操作)的页面压缩。
今天我在 The Heap 上,正在查看我认为可以改进的查询计划。然而,它创造了一些东西,动摇了我对 SQL Server 查询优化器的信念。如果sql-server甚至不能计数到 100%,我还可以信任它吗?
表的特点:
date_entered
列有没有人以前见过这个,是什么导致计划看起来如此扭曲?
我有一个看起来像这样的查询:
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) 我正在尝试编写一个查询,该查询仅根据 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 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 操作?
sql-server ×9
oracle ×3
mysql ×2
optimization ×2
performance ×2
postgresql ×2
compression ×1
cte ×1
delete ×1
join ×1
select ×1
sqlite ×1
ssms ×1
t-sql ×1
truncate ×1
union ×1