我通常通过首先构造一个使用正确计划的查询,然后将其复制到类似的查询中来创建计划指南。但是,这有时很棘手,尤其是在查询不完全相同的情况下。从头开始创建计划指南的正确方法是什么?
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 怪癖。
我想要一种方法来确定给定数据库中的哪些列通过 PK/FK 关系连接。我可以通过以下方式返回给定表的 PK/FK 信息
SELECT *
FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE AS cu
WHERE EXISTS (
SELECT tc.*
FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS AS tc
WHERE tc.CONSTRAINT_CATALOG = 'MyDatabase'
AND tc.TABLE_NAME = 'MyTable'
/*AND tc.CONSTRAINT_TYPE = 'PRIMARY KEY'*/
AND tc.CONSTRAINT_NAME = cu.CONSTRAINT_NAME);
GO
Run Code Online (Sandbox Code Playgroud)
但是对于从这样的查询返回的 PK,我如何建立关联的 FK(假设有一个)?
我知道您还可以通过以下方式获取引用的表:
SELECT CONSTRAINT_NAME = name,
FOREIGN_SCHEMA = OBJECT_SCHEMA_NAME(parent_object_id),
FOREIGN_TABLE = OBJECT_NAME(parent_object_id),
REFERENCED_SCHEMA = OBJECT_SCHEMA_NAME(referenced_object_id),
REFERENCED_TABLE = OBJECT_NAME(referenced_object_id)
FROM sys.foreign_keys
WHERE OBJECT_NAME(referenced_object_id) = 'MyTable';
GO
Run Code Online (Sandbox Code Playgroud)
但我现在正在努力获得明确的列引用。
我正在为 QlikView 创建一个脚本生成器。要生成脚本,我需要约束和关联的链接。我需要任何给定列(如果有)的所有约束信息。
我想构建一个数据库类来保存给定数据库的所有信息。database.table.column.constraints然后将使用该类结构来获取 PK/FK 上不同列之间的匹配。
很明显,有些列只有 FK,在这种情况下,我还想检索相应键的 PK 信息;有些将只有PK,然后我想要相反的。有些当然可以两者兼而有之。
create table T(ID int identity primary key)
insert into T default values
insert into T default values
go
select cast(ID as varchar(10)) as ID
from T
where ID = 1
Run Code Online (Sandbox Code Playgroud)
上面的查询在查询计划中有一个警告。
<Warnings>
<PlanAffectingConvert ConvertIssue="Cardinality Estimate" Expression="CONVERT(varchar(10),[xx].[dbo].[T].[ID],0)" />
</Warnings>
Run Code Online (Sandbox Code Playgroud)
为什么它有警告?
字段列表中的强制转换如何影响基数估计?
sql-server execution-plan type-conversion sql-server-2012 cardinality-estimates
我安装了 PostgreSQL,因为我需要恢复.backup我收到的一个大文件以上传到另一个平台(它有 3800 万行,显然太大了,无法以任何其他方式导出)。当我尝试在 pgAdmin 4 中“恢复”时,我收到以下消息:
请在首选项对话框中配置 PostgreSQL 二进制路径。
这只是 PostgreSQL 文件夹的路径吗?我在 PostgreSQL 站点上找不到关于此的文档。我能找到的只有:
使用二进制路径节点中的字段指定 PostgreSQL 二进制实用程序和 EnterpriseDB Postgres Advanced Server 二进制实用程序的路径。
除了通过 pgAdmin 之外,还有其他更简单的方法来恢复数据库吗?
在 SQL Server 中,行存储表上的非唯一非聚集索引在非聚集索引结构的所有级别合并了基础对象的书签(RID 或聚集键)。书签作为非聚集索引键的一部分存储在所有索引级别。
另一方面,如果非聚集索引是unique,则书签仅存在于索引的叶级别 - 不作为键的一部分(实际上,书签作为一个或多个包含的列存在)。
在 SQL Server 2016 中,可以在面向列的表(具有聚集列存储索引的表)上构建非聚集 b 树索引。
在某些情况下,INSERT INTO <tablename> (WITH TABLOCK)由于日志记录最少,执行 an会更快。这些情况包括将数据库置于BULK_LOGGED恢复模型中。
是否有任何其他潜在的性能优势,使用WITH TABLOCK上INSERT的空白表时,数据库(tempdb数据库)使用SIMPLE恢复模式?
我正在使用 SQL Server 2012 标准版。
我的用例是在使用 的存储过程中创建然后立即填充临时表INSERT...SELECT,其中可能包含多达几百万行。我尽量避免这种tempdb滥用,但有时需要这样做。
我正在尝试构建一个需要 require 的案例TABLOCK。它似乎不会伤害任何东西,并且可能有好处。我试图弄清楚是否有足够的潜在好处将它添加到我们的代码库中的任何地方,我确信没有其他进程想要写入表。
我通常使用集群 PK 插入新创建的本地临时表,但有时会使用堆。
我们已启用 sp_configure 'tempdb metadata memory-optimized' = 1,现在 tempdb 元数据在我们的一台服务器上占用了 400 GB 以上,并且还在继续增长。内存使用量有所下降,但通常它的内存使用量会不断增加。我们已经有几次服务器实际上崩溃了,因为其他系统进程没有足够的内存来修改 tempdb,这导致整个服务器宕机。
如何防止 SQL Server 内存中优化的 tempdb 元数据不断增长并使我的服务器崩溃?如果有的话,我可以查看哪些其他信息来找到消耗如此多内存的内容?
以下查询当前返回 438 GB。
SELECT SUM(domc.pages_kb / 1024.0 / 1024.0) AS pages_gb
FROM sys.dm_os_memory_clerks AS domc
WHERE domc.type LIKE 'MEMORYCLERK_XTP'
Run Code Online (Sandbox Code Playgroud)
以下查询提供的数据是内存的最大使用量(290 GB)是 memory_consumer_id 为 113 - 'LOB Page Allocator'。它没有object_id 或xtp_object_id,所以我猜它是一个数据库范围的对象。
SELECT ddxmc.memory_consumer_id
, ddxmc.memory_consumer_type_desc
, ddxmc.memory_consumer_desc
, ddxmc.object_id
, ddxmc.xtp_object_id
, ddxmc.used_bytes / 1024.0 / 1024.0 / 1024.0 AS used_gb
FROM sys.dm_db_xtp_memory_consumers AS ddxmc
ORDER BY ddxmc.allocated_bytes …Run Code Online (Sandbox Code Playgroud) sql-server memory tempdb memory-optimized-tables sql-server-2019
查询:
SELECT
name AS TableName,
create_date AS CreatedDate,
modify_date as ModifyDate
FROM sys.tables
order by ModifyDate;
Run Code Online (Sandbox Code Playgroud)
...将告诉我上次创建和修改表的时间(从 DDL 的角度)。但我想知道上次从表中插入或删除实际数据的时间。是否可以在 SQL Server 中获得它?
我们的供应商更改了整个数据库中几乎每一列的列宽。数据库大约 7TB,9000 多个表。我们正在尝试在具有 55 亿行的表上创建索引。在供应商升级之前,我们可以在 2 小时内创建索引。现在需要几天时间。他们所做的是将任何 varchar(xx) 大小增加到 varchar(256)。所以大多数列曾经是 varchar(18) 或 varchar(75) 等。
无论如何,主键由 6 列组成,组合宽度为 126 个字符。现在升级后,主键是 1283 个字符,这违反了 SQL Server 900 个字符的限制。整个表列宽度从 1049 的总组合 varchar 计数变为 4009 的总组合 varchar 计数。
数据没有增加,表不会占用比所有列宽增加之前更多的“空间”,但是创建像索引这样简单的东西的性能现在花费了不合理的时间。
任何人都可以解释为什么当唯一要做的就是增加列的大小时,为什么创建和索引需要这么长时间?
我们尝试创建的索引是非聚集的,因为 pk 是聚集索引。在多次尝试创建索引后,我们放弃了。我认为它运行了 4 或 5 天而没有完成。
我在非生产环境中尝试了这一点,方法是拍摄文件系统快照并将数据库放在更安静的服务器上。
我能找到的最接近我想要做的是如何复制相关行,但我的经验不足让我迷失了方向。基本上,我想复制一些记录,更改一列并将它们插入同一个表中(因此它几乎是原始数据的副本)。
表menuship是食物菜单的哈希表(表中的每一行都将标识一个菜单类别(例如开胃菜、主菜或甜点)和产品(鱼和薯条)。
表结构:
CREATE TABLE `menuship3` (
`id` int(10) NOT NULL AUTO_INCREMENT,
`headhash` char(40) DEFAULT NULL,
`menucardhash` char(40) DEFAULT NULL,
`menucathash` char(40) DEFAULT NULL,
`producthash` char(40) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `headhash` (`headhash`)
) ENGINE=InnoDB AUTO_INCREMENT=52 DEFAULT CHARSET=utf8
Run Code Online (Sandbox Code Playgroud)
在编程界,我会说我想“分叉”我的数据......
如果我的表格内容是这样的:
| ID | 头哈希 | 菜单卡哈希 | 菜单现金 | 产品哈希 |
|---|---|---|---|---|
| 1 | 啊啊啊啊 | 啊啊啊啊 | 啊啊啊啊 | 啊啊啊啊 |
| 2 | 啊啊啊啊 | 啊啊啊啊 | 啊啊啊啊 | bbb |
| 3 | 啊啊啊啊 | 啊啊啊啊 | 啊啊啊啊 | 抄送 |
| 4 | 啊啊啊啊 | 啊啊啊啊 | bbb | 滴滴 |
| 5 | 啊啊啊啊 | 啊啊啊啊 | 抄送 | ee |
| 6 | 啊啊啊啊 | 其他 … |
sql-server ×8
columnstore ×1
cte ×1
foreign-key ×1
insert ×1
memory ×1
metadata ×1
mysql ×1
performance ×1
pgadmin ×1
pgadmin-4 ×1
postgresql ×1
restore ×1
t-sql ×1
tempdb ×1