mysql - 在不带 "where"的连接上使用索引

标签 mysql sql database database-administration

我试图了解如果第一个表上的位置没有限制,是否可以在联接上使用索引。

注意:这不是逐行的实际案例用法,只是我出于理解目的而一起起草的内容。不要指出明显的“您想通过此模式获得什么?”、“您应该使用 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/

相关文章:

sql - 由于磁盘空间/内存错误而更改表中的数据类型

mysql - 从表 1 中选择所有内容,并使用表 2 和表 3 中的平均值和不同值

超过 2 页的 PHP 提交表单到 MySQL 表

php - 有什么方法可以减小文本的大小?

sql - 合并两个选择语句

database - 有人使用 CouchDB 吗?

mysql - 按列分组时选择零计数

mysql - 不循环引用 MYSQL 结果集

php - php 5.6 中的 mysql 问题未选择数据库

sql - 聚合查询中切换大小写