我试图了解如果第一个表上的位置没有限制,是否可以在联接上使用索引。
注意:这不是逐行的实际案例用法,只是我出于理解目的而一起起草的内容。不要指出明显的“您想通过此模式获得什么?”、“您应该使用 UNSIGNED”或类似内容,因为这不是问题。
注2:这个MySQL JOINS without where clause有某种相关但不相同
架构:
CREATE TABLE posts (
id_post INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
text VARCHAR(100)
);
CREATE TABLE related (
id_relation INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
id_post1 INT NOT NULL,
id_post2 INT NOT NULL
);
CREATE INDEX related_join_index ON related(id_post1) using BTREE;
查询:
EXPLAIN SELECT * FROM posts FORCE INDEX FOR JOIN(PRIMARY) INNER JOIN related ON id_post=id_post1 LIMIT 0,10;
SQL fiddle :http://sqlfiddle.com/#!2/84597/3
正如您所看到的,索引正在第二个表上使用,但引擎正在第一个表上进行全表扫描(FORCE INDEX 只是为了突出显示一般问题)。
我想了解是否也可以在左侧获得“ref”。
谢谢!
更新:如果第一个表的记录明显多于第二个表,则事物交换:引擎对第一个表使用索引,对第二个表使用全表扫描 http://sqlfiddle.com/#!2/3a3bb/1尽管如此,仍然无法在两者上使用索引。
最佳答案
DBMS 有一个优化器来找出执行查询的最佳计划。由优化器决定是使用索引还是直接读取表。
当 DBMS 期望仅从表中读取少量记录(例如仅所有行的 1%)时,索引就有意义。但是一旦它期望读取许多记录(例如所有行的 99%),它就不会使用索引。阈值可能低至 5%(即 <= 5% -> 索引;> 5% 表扫描)。
也有异常(exception)。一种是索引包含所需的所有列。那么根本不需要读取表本身。另一种情况可能是优化器认为尽管必须读取许多行,但索引访问可能会更快。优化器也有可能只是猜测错误。
关于mysql - 在不带 "where"的连接上使用索引,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27899492/