我有两个结果集:
rs1:
id name
serial text
________________
1 Nick
....................
1233112 Pete
Run Code Online (Sandbox Code Playgroud)
rs2:
id name
serial text
________________
123121 Mike
....................
221233112 Junior
Run Code Online (Sandbox Code Playgroud)
如果我们写一个查询:
SELECT *
FROM
(
SELECT *
FROM rs1
UNION ALL
SELECT *
FROM rs2
) as rs
OFFSET 100000 LIMIT 10;
Run Code Online (Sandbox Code Playgroud)
查询结果是如何计算的?将使用什么算法?
我相信服务器执行惰性评估是指不加载整个联合,对其进行迭代,然后返回所需的结果。
如果您描述了其他 SQL 服务器中使用的算法作为补充,我将很高兴。
UPD:我对数据库内部结构很陌生,不知道是否可以向 sql-server 本身询问查询的执行计划。
这是一个查询计划:
"Limit (cost=77.11..77.88 rows=10 width=522)"
" -> Append (cost=0.00..140.18 rows=1818 width=522)"
" -> Seq Scan on tbl (cost=0.00..70.09 rows=909 width=522)"
" -> Seq Scan on …Run Code Online (Sandbox Code Playgroud) 首先,我问这个的原因是因为我觉得我有一个数据库 - 根据我自己的估计 - 应该用大量 I/O 杀死磁盘,因为索引不适合内存,但在实际上它仍然表现良好。
让我们从相关表开始:
CREATE TABLE `search` (
`a` bigint(20) unsigned NOT NULL,
`b` int(10) unsigned NOT NULL,
`c` int(10) unsigned DEFAULT NULL,
`d` int(10) unsigned DEFAULT NULL,
`e` varchar(255) DEFAULT NULL,
`f` varchar(255) DEFAULT NULL,
`g` varchar(255) DEFAULT NULL,
`h` varchar(255) DEFAULT NULL,
`i` varchar(255) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
Run Code Online (Sandbox Code Playgroud)
该a列是一个 8 字节的数字,其中编码了时间戳(以秒为单位)。该表有一个PARTITION BY RANGE (a), 将表分成每月分区。这是因为我们只在数据库中保留了 24 个月,其余的都被清除了。
该表每月增长约 2 亿行;整个表包含大约 50 亿行。
它运行的服务器有大约 360GB 的内存,其中 300GB 是为 MySQL …
我有3张桌子。#a是一个主表和两个辅助表,#b并且#c.
create table #a (a int not null, primary key (a asc)) ;
create table #b (b int not null, primary key (b asc)) ;
create table #c (c int not null, primary key (c asc)) ;
insert into #a (a)
select x*10 + y
from (values(0),(1),(2),(3),(4),(5),(6),(7),(8),(9))x(x)
cross join (values(0),(1),(2),(3),(4),(5),(6),(7),(8),(9))y(y) ;
insert into #b (b)
select a from #a where a % 5 > 0 ;
insert into #c (c)
select a from #a …Run Code Online (Sandbox Code Playgroud) 在我在 Linux 上默认安装的 SQL Server 2017 中,/var/opt/mssql/data我看到以下数据库,
master.mdf- master 数据库- 记录 SQL Server 实例的所有系统级信息。model.mdf-模型数据库- 用作在 SQL Server 实例上创建的所有数据库的模板。对模型数据库所做的修改,例如数据库大小、排序规则、恢复模型和其他数据库选项,将应用于之后创建的任何数据库。msdbdata.mdf- msdb 数据库- SQL Server 代理使用它来安排警报和作业。tempdb.mdf- tempdb 数据库- 是用于保存临时对象或中间结果集的工作区。所有这些数据库实际上都有很好的文档记录。然而,我的安装对资源数据库的遗漏很突出。Resource Database 的描述似乎表明它是自己的数据库,
资源数据库是一个只读数据库,其中包含 SQL Server 附带的所有系统对象。SQL Server 系统对象(例如 sys.objects)在物理上持久保存在 Resource 数据库中,但它们在逻辑上出现在每个数据库的 sys 架构中。资源数据库不包含用户数据或用户元数据。
更令人困惑的是,对于SQL Server 2012,文档说,(不是 2017,这是我正在运行的)
资源的物理性质
Resource 数据库的物理文件名是 mssqlsystemresource.mdf 和 mssqlsystemresource.ldf。这些文件位于
<drive>:\Program Files\Microsoft SQL Server\MSSQL11.<instance_name>\MSSQL\Binn\. 每个 SQL Server …
principal_idin的含义是什么?sys.schemas它何时会与 不同schema_id?
1> SELECT LEFT(name,20), schema_id, principal_id FROM sys.schemas;
2> GO
schema_id principal_id
-------------------- ----------- ------------
dbo 1 1
guest 2 2
INFORMATION_SCHEMA 3 3
sys 4 4
db_owner 16384 16384
db_accessadmin 16385 16385
db_securityadmin 16386 16386
db_ddladmin 16387 16387
db_backupoperator 16389 16389
db_datareader 16390 16390
db_datawriter 16391 16391
db_denydatareader 16392 16392
db_denydatawriter 16393 16393
(13 rows affected)
Run Code Online (Sandbox Code Playgroud)
在内部,我看到 the schema_idcome from sys.sysclsobjswhile the principal_idcome fromsys.syssingleobjrefs的r.indepid字段。
我正在从 SQL Server 过渡到 Postgres,对我来说最需要消化的事情之一是不存在用于对 Postgres 中的数据进行排序的“聚集键”。
有人可以分享一下他们对 Postgres 如何避免内部排序数据集的需要以及它如何与大型堆表一起工作并仍然提供卓越性能的想法吗?
postgresql sql-server clustered-index database-internals heap
在准备我之前的Constant Scan 问题时,我VALUES以各种方式进行了试验,并遇到了关于连接的事情,VALUES这对我来说很奇怪。
设置很简单
CREATE TABLE #data ([Id] int);
INSERT INTO #data VALUES (101), (103);
Run Code Online (Sandbox Code Playgroud)
然后有一个查询
DECLARE @id1 int = 101, @id2 int = 102;
SELECT *
FROM (VALUES (@id1), (@id2)) p([Id])
FULL HASH JOIN #data d ON d.[Id] = p.[Id];
Run Code Online (Sandbox Code Playgroud)
没有什么特别之处。如果你运行它,它会工作并产生它的结果。这是它的执行计划
从VALUES然而删除行
SELECT *
FROM (VALUES (@id1)) p([Id])
FULL HASH JOIN #data d ON d.[Id] = p.[Id];
Run Code Online (Sandbox Code Playgroud)
导致优化器失败
消息 8622,级别 16,状态 1,第 1 行
查询处理器无法生成查询计划...
为什么?有没有办法(除了将参数放入临时表)使用哈希算法使其工作?
注意:这不是真正的设备,用于研究优化器行为和功能。
上面的例子在
Microsoft SQL …
SQL Server 跟踪各种内部位图中的页面分配。其中包括全局分配映射 (GAM) 和页面可用空间 (PFS) 页。我们知道 GAM 页面以511232页的设定间隔出现,PFS 页面以 8088 页的设定间隔出现。
如果数据文件足够大,这种重复最终将导致 GAM 和 PFS 中的下一个页面。计算一下,这发生在 1,011 个 GAM 或 63,904 个 PFS 页(页码 516,855,552)之后。这相当于一个略低于 4TB 的操作系统文件。由于单个数据文件的最大大小为 16TB(源),因此这是允许的。
我的问题:当单个数据文件达到 4TB 时,哪种页面类型是页面 516855552 - GAM 还是 PFS?另一个去哪儿了?Paul Randal 的这条评论表明它被分流到 GAM 范围内其他未使用的页面之一:
除第一个之外的 GAM 区有 GAM、SGAM、DIFF_MAP、ML_MAP。每 4TB GAM 范围还将有一个 PFS 页。
我发现这里引用了这一点,但没有明确解释:
Run Code Online (Sandbox Code Playgroud)-- There may be an issue with the ML map page position -- on the four extents where PFS …
使用临时数据库;
走
删除表 tbl ;
走
创建表 tbl
(
i SQL_VARIANT 非空
);
走
插入 tbl (i)
值 (1) ;
走
从 tbl 中选择我;
走
DBCC IND ('tempdb','tbl',-1) ;
走
DBCC TRACEON (3604) ; -- 页面转储将进入控制台
走
DBCC 页面 ('tempdb',1,157,3) ;
走
我正在使用具有以下格式的表格:
CREATE TABLE dbo.ID_STORE
( WORKING_ID bigint PRIMARY KEY CLUSTERED )
Run Code Online (Sandbox Code Playgroud)
该表存储了大约 200 万行,但存储的 id 不是连续的,MAX(WORKING_ID)-MIN(WORKING_ID) 大约是 24百万。
当我查看已用空间时,我发现大约 57 兆字节,而我预期略高于 2 10 ^ 6 x 8 = 16 兆字节。谁能解释一下区别?
编辑:这些数字是从第一次导入到所述表中获得的。该表在填充之前也会被截断。
sql-server ×7
optimization ×2
postgresql ×2
catalogs ×1
heap ×1
join ×1
linux ×1
memory ×1
mysql ×1
mysql-5.6 ×1
percona ×1
schema ×1
storage ×1
users ×1