Hit*_*ony 7 mysql indexing hash b-tree
也许这可能是菜鸟,但我正在搞几张桌子.
我有表A约45,000条记录
我有表B大约150万条记录
我有一个问题:
update
schema1.tablea a
inner join (
SELECT DISTINCT
ID, Lookup,
IDpart1, IDpart2
FROM
schema1.tableb
WHERE
IDpart1 is not NULL
AND
Lookup is not NULL
ORDER BY
ID,Lookup
) b Using(ID,Lookup)
set
a.Elg_IDpart1 = b.IDpart1,
a.Elg_IDpart2 = b.IDpart2
where
a.ID is NOT NULL
AND
a.Elg_IDpart1 is NULL
Run Code Online (Sandbox Code Playgroud)
所以我在ID,Lookup上强制索引.每个表都有这些列的索引,但由于子查询我强制它.
它正在运行,它真的应该采取,我想在5分钟之内......
我的问题是关于索引,而不是查询.
我知道你不能在有序索引中使用哈希索引.
我目前在ID,Lookup上都有索引,并且作为一个索引,它是一个B-Tree索引.基于我的WHEREClause,哈希索引是否适合作为优化技术?
我可以有一个哈希索引,其余的索引是B树索引吗?
这不是主要关键字段.
我会发布我的解释,但我更改了这些表上的名称.基本上它只是为ID使用索引...而不是使用ID,Lookup,我想强制它使用它们,或者至少把它变成另一种索引,看看是否有帮助?
现在我知道MySQL足够聪明,可以确定哪个索引最合适,那么它正在做什么?Lookup字段映射ID的第一部分和第二部分......
对此有任何帮助或见解表示赞赏.
一个EXPLAIN在UPDATE我拿出子查询后.
+----+-------------+-------+------+-----------------------------+--------------+---------+-------------------+-------+-------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+-------+------+-----------------------------+--------------+---------+-------------------+-------+-------------+ | 1 | SIMPLE | m | ALL | Lookup_Idx,ID_Idx,ID_Lookup | | | | 44023 | Using where | | 1 | SIMPLE | c | ref | ID_LookupIdx | ID_LookupIdx | 5 | schema1.tableb.ID | 4 | Using where | +----+-------------+-------+------+-----------------------------+--------------+---------+-------------------+-------+-------------+
tablea 相关指标:
ID_LookupIdx (ID, Lookup)tableb 相关指标:
ID (ID)Lookup_Idx (Lookup)ID_Lookup_Idx (ID, Lookup)所有索引都是普通的B树.
egg*_*yal 13
首先,处理您提出的具体问题:
我目前在ID,Lookup上都有索引,并且作为一个索引,它是一个B-Tree索引.基于我的
WHEREClause,哈希索引是否适合作为优化技术?
如CREATE INDEX语法下所述:
+----------------+--------------------------------+ | Storage Engine | Permissible Index Types | +----------------+--------------------------------+ | MyISAM | BTREE | | InnoDB | BTREE | | MEMORY/HEAP | HASH, BTREE | | NDB | BTREE, HASH (see note in text) | +----------------+--------------------------------+
因此,在考虑HASH索引之前,应该意识到它仅在MEMORY和NDB存储引擎中可用:因此甚至可能不是您的选择.
此外,请注意,单独ID和Lookup单独组合的索引可能不是最佳的,因为您的WHERE谓词也会过滤,tablea.Elg_IDpart1并且tableb.IDpart1您也可能从这些列的索引中受益.
我可以有一个哈希索引,其余的索引是B树索引吗?
如果存储引擎支持所需的索引类型,您可以根据需要混合它们.
而不是使用ID,Lookup,我想强迫它使用它们,或者至少把它变成另一种索引,看看是否有帮助?
您可以使用索引提示强制MySQL使用不同的索引,而不是优化器本来会选择的索引.
现在我知道MySQL足够聪明,可以确定哪个索引最合适,那么它正在做什么?
它通常很聪明,但并非总是如此.然而,在这种情况下,它可能已经确定索引的基数是这样的,以便最好使用它所选择的那些.
现在,根据您使用的MySQL版本,从子查询派生的表可能没有任何可用于进一步处理的索引:因此,连接b可能需要对该派生表进行全面扫描(此处的信息不足)你的问题确切地确定了这可能有多大的问题,但 schema1.tableb有150万条记录表明它可能是一个重要因素).
有关更多信息,请参阅子查询优化.
因此,如果可能的话,应该尽量避免使用派生表.在这种情况下,不出现任何目的,以派生表作为一个可以简单地连接schema1.tablea和schema1.tableb直接:
UPDATE schema1.tablea a
JOIN schema1.tableb b USING (ID, Lookup)
SET a.Elg_IDpart1 = b.IDpart1,
a.Elg_IDpart2 = b.IDpart2
WHERE a.Elg_IDpart1 IS NULL
AND a.ID IS NOT NULL
AND b.IDpart1 IS NOT NULL
AND b.Lookup IS NOT NULL
ORDER BY ID, Lookup
Run Code Online (Sandbox Code Playgroud)
唯一丢失的是DISTINCT记录过滤器,但重复记录将简单地(尝试)再次用相同的值覆盖更新的值 - 这将没有任何效果,但可能已经证明非常昂贵(特别是有这么多记录)那张桌子).
使用的ORDER BY派生表是毫无意义的,因为它可能不能依赖,来实现特定顺序的UPDATE,而在这个修订版也将确保覆盖以前的任何更新发生在特定的顺序:但是,这是必要的?也许它可以删除并保存在任何排序操作上.
应该检查WHERE子句中的谓词:它们是否都是必要的(例如,由于谓词将消除任何此类记录,因此NOT NULL检查a.ID并且b.Lookup是多余NULL的JOIN)?
总而言之,这让我们:
UPDATE schema1.tablea a
JOIN schema1.tableb b USING (ID, Lookup)
SET a.Elg_IDpart1 = b.IDpart1,
a.Elg_IDpart2 = b.IDpart2
WHERE a.Elg_IDpart1 IS NULL
AND b.IDpart1 IS NOT NULL
Run Code Online (Sandbox Code Playgroud)
只有当性能仍然不令人满意时,才应该进一步研究索引.是否将相关列(即JOIN和WHERE谓词中使用的列)编入索引?是否选择了MySQL使用的索引(请记住,每个表只能使用一个索引进行查找:用于测试JOIN谓词和过滤谓词:可能需要一个合适的复合索引)?通过使用EXPLAIN进一步调查此类问题来检查查询执行计划.
| 归档时间: |
|
| 查看次数: |
11345 次 |
| 最近记录: |