标签: join

MySQL 在连接另一个表时不使用索引

我有两个表,第一个表包含 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)

mysql performance index join order-by

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

如何优化查询,使其先搜索一个索引,然后再搜索另一个索引

我有两组来自卫星数据的地球测量值,每组都有时间场(平均朱利安日期的 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)

并且执行的计划是:

只有 mjd 约束

排序后,有 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)

performance index join sql-server spatial query-performance

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

将两个事件表合并为一个时间线

给定两个表:

CREATE TABLE foo (ts timestamp, foo text);
CREATE TABLE bar (ts timestamp, bar text);
Run Code Online (Sandbox Code Playgroud)

我想编写一个查询,对于回报值tsfoo以及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 join window-functions

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

计算系列中每个日期有多少日期范围的最快方法

我有一个看起来像这样的表(在 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)

postgresql join functions postgresql-9.4

12
推荐指数
2
解决办法
3555
查看次数

是否有任何数据库引擎会根据现有外键来直觉连接条件?

令我感到奇怪的是,当我定义了外键时,引擎无法使用此信息自动找出正确的 JOIN 表达式,而是要求我重新键入相同的子句。是否有任何数据库,也许是某种研究项目,可以检查现有的外键?

join foreign-key database-recommendation feature-comparison

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

MS Access 中的完全外部联接

我有两个员工名单:

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 …

join ms-access query

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

如何改进行估计以减少溢出到 tempdb 的机会

我注意到,当 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)

join sql-server optimization

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

嵌套在 OUTER JOIN 中的 INNER JOIN 的语法与查询结果

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)

在此处输入图片说明

join sql-server syntax sql-server-2012

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

为什么嵌套循环连接只支持左连接?

在 Craig Freedman 的博客Nested Loops Join 中,他解释了为什么嵌套循环联接不能支持右外联接

问题是我们多次扫描内表——外连接的每一行扫描一次。在这些多次扫描期间,我们可能会多次遇到相同的内部行。在什么时候我们可以得出结论,特定的内部行没有或不会加入?

有人可以用一种非常简单和有教育意义的方式解释一下吗?

这是否意味着循环从外表 ( R1) 开始并扫描内表 ( R2)?

我知道对于R1不与 连接的值,R2应将其替换为 aNULL以便结果集变为 ( NULL, R2)。对我来说,R2R1不加入时似乎不可能返回一个值,因为它不知道R2要返回哪个值。但这不是它的解释方式。或者是吗?

SQL Server会在事实上优化(经常替换)RIGHT JOINLEFT JOIN,但问题是解释为什么它在技术上是不可能的NESTED LOOPS JOIN使用/支持RIGHT JOIN逻辑。

join sql-server database-internals

11
推荐指数
2
解决办法
1525
查看次数

为什么不使用 sys.query_store_plan 加入消除工作?

以下是查询存储遇到的性能问题的简化:

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,但执行计划并不像预期的那样使用连接消除

  1. DMV 没有投射任何属性。
  2. DMV 主键plan_id不能复制临时表中的行
  3. 使用了 A LEFT JOIN,因此无法T消除from中的任何行。

执行计划

平面图

为什么会这样,在这里可以做些什么来消除连接?

performance join sql-server execution-plan query-store query-performance

10
推荐指数
1
解决办法
386
查看次数