我有两个表,第一个表包含 CMS 中的所有文章/博客文章。其中一些文章也可能出现在杂志中,在这种情况下,它们与包含杂志特定信息的另一个表具有外键关系。
这是这两个表的 create table 语法的简化版本,其中删除了一些非必要的行:
CREATE TABLE `base_article` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`date_published` datetime DEFAULT NULL,
`title` varchar(255) NOT NULL,
`description` text,
`content` longtext,
`is_published` int(11) NOT NULL DEFAULT '0',
PRIMARY KEY (`id`),
KEY `base_article_date_published` (`date_published`),
KEY `base_article_is_published` (`is_published`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
CREATE TABLE `mag_article` (
`basearticle_ptr_id` int(11) NOT NULL,
`issue_slug` varchar(8) DEFAULT NULL,
`rubric` varchar(75) DEFAULT NULL,
PRIMARY KEY (`basearticle_ptr_id`),
KEY `mag_article_issue_slug` (`issue_slug`),
CONSTRAINT `basearticle_ptr_id_refs_id` FOREIGN KEY (`basearticle_ptr_id`) REFERENCES `base_article` (`id`)
) ENGINE=InnoDB DEFAULT …Run Code Online (Sandbox Code Playgroud) 我有两组来自卫星数据的地球测量值,每组都有时间场(平均朱利安日期的 mjd)和地理位置(GeoPoint,空间),我正在寻找两组之间的巧合,以便它们的时间匹配阈值3 小时(或 0.125 天),它们之间的距离在 200 公里以内。
我已经为表和空间表上的 mjd 字段创建了索引。
当我刚刚加入时间限制时,数据库会在 8 秒内计算 100,000 个匹配项,并计算该时间内所有 100,000 个匹配项的距离。查询如下所示:
select top 100000 h.Time, m.Time, h.GeoPoint.STDistance(m.GeoPoint)/1000.0
from L2V5.dbo.header h join L2.dbo.MLS_Header m
on h.mjd between m.mjd-.125 and m.mjd+.125
option( table hint ( h, index(ix_MJD) ), table hint( m, index(ix_MJD) ) )
Run Code Online (Sandbox Code Playgroud)
并且执行的计划是:

排序后,有 9 个距离在 200 公里以下,因此存在匹配项。问题是,当我添加距离约束并运行它时,
select top 10 h.Time, m.Time, h.GeoPoint.STDistance(m.GeoPoint)/1000.0
from L2V5.dbo.header h join L2.dbo.MLS_Header m
on h.mjd between m.mjd-.125 and m.mjd+.125
and h.GeoPoint.STDistance(m.GeoPoint)<200000
option( table hint ( h, index(ix_MJD) …Run Code Online (Sandbox Code Playgroud) 给定两个表:
CREATE TABLE foo (ts timestamp, foo text);
CREATE TABLE bar (ts timestamp, bar text);
Run Code Online (Sandbox Code Playgroud)
我想编写一个查询,对于回报值ts,foo以及bar代表最新的值的统一视图。换句话说,如果foo包含:
ts | foo
--------
1 | A
7 | B
Run Code Online (Sandbox Code Playgroud)
并bar包含:
ts | bar
--------
3 | C
5 | D
9 | E
Run Code Online (Sandbox Code Playgroud)
我想要一个返回的查询:
ts | foo | bar
--------------
1 | A | null
3 | A | C
5 | A | D
7 | B | D
9 | B …Run Code Online (Sandbox Code Playgroud) 我有一个看起来像这样的表(在 PostgreSQL 9.4 中):
CREATE TABLE dates_ranges (kind int, start_date date, end_date date);
INSERT INTO dates_ranges VALUES
(1, '2018-01-01', '2018-01-31'),
(1, '2018-01-01', '2018-01-05'),
(1, '2018-01-03', '2018-01-06'),
(2, '2018-01-01', '2018-01-01'),
(2, '2018-01-01', '2018-01-02'),
(3, '2018-01-02', '2018-01-08'),
(3, '2018-01-05', '2018-01-10');
Run Code Online (Sandbox Code Playgroud)
现在我想计算给定日期和每种类型,计算dates_ranges每个日期有多少行。零可以省略。
想要的结果:
+-------+------------+----+
| kind | as_of_date | n |
+-------+------------+----+
| 1 | 2018-01-01 | 2 |
| 1 | 2018-01-02 | 2 |
| 1 | 2018-01-03 | 3 |
| 2 | 2018-01-01 | 2 |
| …Run Code Online (Sandbox Code Playgroud) 令我感到奇怪的是,当我定义了外键时,引擎无法使用此信息自动找出正确的 JOIN 表达式,而是要求我重新键入相同的子句。是否有任何数据库,也许是某种研究项目,可以检查现有的外键?
我有两个员工名单:
List A:
StaffID Supervisor
====================
0001234 NULL
0001235 0001234
0001237 0001234
0001239 0001237
Run Code Online (Sandbox Code Playgroud)
和
List B:
StaffID Supervisor
====================
0001234 NULL
0001235 0001234
0001238 0001235
0001239 0001235
Run Code Online (Sandbox Code Playgroud)
我需要以下输出:
StaffID SupervisorA SupervisorB
===================================
0001234 NULL NULL
0001235 0001234 0001234
0001237 0001234 NULL
0001238 NULL 0001235
0001239 0001237 0001235
Run Code Online (Sandbox Code Playgroud)
请注意,列表 A 和列表 B 中的员工 ID 已合并到一个不重复的列表中,并且我已合并了两个列表之间可能不匹配的两个主管详细信息。
查询不必很好。我在每个列表中有大约 8000 条记录,我会很好地运行它。如有必要,我很乐意在之后进行一些小的 Excel 操作。
我想做一个完整的联接,但联接上的 Access 查询设计器属性窗口允许我从表 A 中选择 ALL 并从表 B 中进行匹配、从表 B 中选择 ALL 并从表 A 中进行匹配,或者仅选择在两个 A 中都匹配的那些和 B。
我确信这很简单,但我很少使用 MS …
我注意到,当 tempdb 事件溢出(导致查询缓慢)时,对于特定连接,行估计通常会偏离。我已经看到溢出事件发生在合并和散列连接中,它们通常将运行时间增加 3 到 10 倍。这个问题涉及如何在减少溢出事件机会的假设下改进行估计。
实际行数 40k。
对于此查询,计划显示错误的行估计(11.3 行):
select Value
from Oav.ValueArray
where ObjectId = (select convert(bigint, Value) NodeId
from Oav.ValueArray
where PropertyId = 3331
and ObjectId = 3540233
and Sequence = 2)
and PropertyId = 2840
option (recompile);
Run Code Online (Sandbox Code Playgroud)
对于此查询,计划显示了良好的行估计(56k 行):
declare @a bigint = (select convert(bigint, Value) NodeId
from Oav.ValueArray
where PropertyId = 3331
and ObjectId = 3540233
and Sequence = 2);
select Value
from Oav.ValueArray
where ObjectId = @a
and PropertyId = 2840
option (recompile); …Run Code Online (Sandbox Code Playgroud) TLDR;如果您查看 2 个执行计划,是否可以轻松回答哪个更好?我故意没有创建索引,所以更容易看到发生了什么。
继续我之前的问题,我们发现不同连接样式(即嵌套与传统)之间的查询性能差异,我意识到嵌套语法也会修改查询的行为。考虑以下 2 个查询。
SELECT a.*, m.*, n.*
FROM dbo.Autos a
LEFT JOIN dbo.Models m
JOIN dbo.Manufacturers n -- <-- Nested INNER JOIN
ON n.ManufacturerID = m.ManufacturerID
ON m.ModelID = a.ModelID
Run Code Online (Sandbox Code Playgroud)

这并不一定使制造商加入,以包括与ModelID自动行是不是在型号表。

使用传统语法,我们必须将 Manufactures 的连接更改为外部连接,就像这样……但这会改变查询计划。
SELECT a.*, m.*, n.*
FROM dbo.Autos a
LEFT JOIN dbo.Models m
ON m.ModelID = a.ModelID
LEFT JOIN dbo.Manufacturers n -- <-- Now LEFT OUTER JOIN
ON n.ManufacturerID = m.ManufacturerID
Run Code Online (Sandbox Code Playgroud)

在 Craig Freedman 的博客Nested Loops Join 中,他解释了为什么嵌套循环联接不能支持右外联接:
问题是我们多次扫描内表——外连接的每一行扫描一次。在这些多次扫描期间,我们可能会多次遇到相同的内部行。在什么时候我们可以得出结论,特定的内部行没有或不会加入?
有人可以用一种非常简单和有教育意义的方式解释一下吗?
这是否意味着循环从外表 ( R1) 开始并扫描内表 ( R2)?
我知道对于R1不与 连接的值,R2应将其替换为 aNULL以便结果集变为 ( NULL, R2)。对我来说,R2当R1不加入时似乎不可能返回一个值,因为它不知道R2要返回哪个值。但这不是它的解释方式。或者是吗?
SQL Server会在事实上优化(经常替换)RIGHT JOIN用LEFT JOIN,但问题是解释为什么它在技术上是不可能的NESTED LOOPS JOIN使用/支持RIGHT JOIN逻辑。
以下是查询存储遇到的性能问题的简化:
CREATE TABLE #tears
(
plan_id bigint NOT NULL
);
INSERT #tears (plan_id)
VALUES (1);
SELECT
T.plan_id
FROM #tears AS T
LEFT JOIN sys.query_store_plan AS QSP
ON QSP.plan_id = T.plan_id;
Run Code Online (Sandbox Code Playgroud)
该plan_id列被记录为 的主键sys.query_store_plan,但执行计划并不像预期的那样使用连接消除:
plan_id不能复制临时表中的行LEFT JOIN,因此无法T消除from中的任何行。为什么会这样,在这里可以做些什么来消除连接?
performance join sql-server execution-plan query-store query-performance
join ×10
sql-server ×5
performance ×3
index ×2
postgresql ×2
foreign-key ×1
functions ×1
ms-access ×1
mysql ×1
optimization ×1
order-by ×1
query ×1
query-store ×1
spatial ×1
syntax ×1