【问题标题】:speed up join between two databases加快两个数据库之间的连接
【发布时间】:2020-11-17 20:30:18
【问题描述】:

我有这个查询,需要 40 秒,有没有办法加快速度?谢谢

SELECT *, last.Date
FROM constant.derogation der             
LEFT JOIN variable.last last             
ON der.code = last.code
WHERE 1 = 1
AND status != 'removed'
ORDER BY status;

+------+-------------+-------+------+---------------+------+---------+------+--------+----------------------------------------------+
| id   | select_type | table | type | possible_keys | key  | key_len | ref  | rows   | Extra                                        |
+------+-------------+-------+------+---------------+------+---------+------+--------+----------------------------------------------+
|    1 | SIMPLE      | der   | ALL  | NULL          | NULL | NULL    | NULL |    318 | Using where; Using temporary; Using filesort |
|    1 | SIMPLE      | last  | ALL  | NULL          | NULL | NULL    | NULL | 250950 | Using where                                  |
+------+-------------+-------+------+---------------+------+---------+------+--------+----------------------------------------------+

这是两个表的结构,两个数据库在同一台服务器上。 我只会从 Last Table 中得到一个值

DLL


| derogation | CREATE TABLE `derogation` (
  `xxx` char(10) NOT NULL,
  `xxx` varchar(100) DEFAULT NULL,
  `code` char(17) DEFAULT NULL,
  `xxx` varchar(20) DEFAULT NULL,
  `xxx` char(6) DEFAULT NULL,
  `xxx` varchar(50) DEFAULT NULL,
  `xxx` varchar(200) DEFAULT NULL,
  `xxxx` varchar(200) DEFAULT NULL,
  `xxxx` varchar(100) DEFAULT NULL,
  `xxxx` datetime DEFAULT NULL,
  `xxx` varchar(100) DEFAULT NULL,
  `xxxx` varchar(20) DEFAULT NULL,
  `xxx` varchar(50) DEFAULT NULL,
  `xxx` varchar(10) DEFAULT NULL,
  `xxx` datetime DEFAULT NULL,
  `xxx` varchar(10) DEFAULT NULL,
  `xxx` datetime DEFAULT NULL,
  `xxx` datetime DEFAULT NULL,
  `status` varchar(20) DEFAULT NULL,
  `xxx` varchar(1000) DEFAULT NULL,
  KEY `code_index_derogation` (`code`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 |


| Last | CREATE TABLE `Last` (
  `code` char(17) DEFAULT NULL,
  `xxx` decimal(10,2) DEFAULT NULL,
  `Date` datetime DEFAULT NULL,
  `xxxx` datetime DEFAULT NULL,
  `xxxx` datetime DEFAULT NULL,
  `xxxx` text DEFAULT NULL,
  `xxxxx` datetime DEFAULT NULL,
  `xxxx` char(6) DEFAULT NULL,
  KEY `idx_Last_Code` (`code`),
  KEY `idx_Last_xxx` (`xxx`),
  KEY `code_index` (`code`),
) ENGINE=InnoDB DEFAULT CHARSET=latin1 |


xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

【问题讨论】:

  • 显示两个表的 DDL。按status 列显示统计信息。
  • 请在每列前面加上表(或表别名),以识别它的来源。这对您来说可能很明显,但对我们来说却不是。
  • 永远不要使用SELECT *。始终只命名(并限定)您实际希望返回的列。
  • 两张表的关系是什么?是 1:1 还是 1:n?
  • @forpas 奇怪,我读到状态属于最后一个,但事实并非如此

标签: mysql performance left-join


【解决方案1】:

您可以使用临时表、暂存表 CTE,也可以为表的列添加索引。 但是使用临时表来加速 SQL 查询的执行总是一个很好的选择。

【讨论】:

  • 这是我的第一个选择,但速度较慢。
  • 我正在使用python查询表,所以我没有想到这个选项,但我可能会使用它。谢谢!
  • 所以请在您的问题中添加 Python 作为标签。
【解决方案2】:

(这个问题很微妙,在这个论坛中经常被忽视。)

不要混合排序规则。您正在加入code,但两个表之间的CHARACTER SETCOLLATION 不同。建议使用 `ALTER TABLE .. CONVERT TO .. 使它们相同。

其他提示:

  • 仅对真正固定长度的列使用CHAR。否则使用VARCHAR

  • 在每张桌子上都有一个PRIMARY KEY

  • 如果你真的期待JOIN,请不要说LEFT JOIN;它给读者增加了困惑。

【讨论】:

    猜你喜欢
    • 2013-12-10
    • 2011-08-07
    • 1970-01-01
    • 2020-02-21
    • 1970-01-01
    • 2013-08-06
    • 1970-01-01
    相关资源
    最近更新 更多