【发布时间】:2012-02-22 18:31:34
【问题描述】:
MySQL 服务器版本:5.1.41 在 Ubuntu 10.04 上
我在修改一些查询时发现 MySQL 的行为有所不同,并想知道它的原因。
基本上我正在创建一个视图。当我查询视图时,结果集是一样的
但是,IN 子句与 OR 子句读取的行数不同。下面是一个简单的例子:
CREATE TABLE country (
id_country int(11) NOT NULL AUTO_INCREMENT,
name varchar(50) NOT NULL,
PRIMARY KEY (id_country)
) ENGINE=InnoDB;
INSERT INTO country (name) VALUES ('A'), ('B'), ('C'), ('D'), ('E'), ('F'), ('G'), ('H');
CREATE TABLE status (
id_status int(11) NOT NULL AUTO_INCREMENT,
id_country int(11) NOT NULL,
status tinyint(4) NOT NULL,
PRIMARY KEY (id_status)
) ENGINE=InnoDB;
ALTER TABLE status ADD INDEX ( id_country );
ALTER TABLE status ADD FOREIGN KEY ( id_country ) REFERENCES test.country (id_country) ON DELETE RESTRICT ON UPDATE RESTRICT ;
INSERT INTO status(id_country, status) VALUES
(1,0), (2,1), (3,0), (4,1), (5,0),(6,1), (7,0), (8,1);
CREATE ALGORITHM=MERGE VIEW view_country
AS
SELECT c.*, s.id_status, s.status
FROM country c JOIN status s ON c.id_country = s.id_country;
下面的 2 条解释语句显示了不同的解析行数
mysql> EXPLAIN EXTENDED SELECT * FROM view_country WHERE id_country IN (1, 2, 3)\G;
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: c
type: range
possible_keys: PRIMARY
key: PRIMARY
key_len: 4
ref: NULL
rows: 3
filtered: 100.00
Extra: Using where
*************************** 2. row ***************************
id: 1
select_type: SIMPLE
table: s
type: ref
possible_keys: id_country
key: id_country
key_len: 4
ref: test.c.id_country
rows: 1
filtered: 100.00
Extra:
2 rows in set, 1 warning (0.00 sec)
使用 OR 子句
mysql> EXPLAIN EXTENDED SELECT * FROM view_country WHERE id_country = 1 OR id_country = 2 OR id_country = 3\G;
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: s
type: ALL
possible_keys: id_country
key: NULL
key_len: NULL
ref: NULL
rows: 8
filtered: 37.50
Extra: Using where
*************************** 2. row ***************************
id: 1
select_type: SIMPLE
table: c
type: eq_ref
possible_keys: PRIMARY
key: PRIMARY
key_len: 4
ref: test.s.id_country
rows: 1
filtered: 100.00
Extra:
2 rows in set, 1 warning (0.00 sec)
如果您查看两个查询中的“行” - 它们加起来不同
与IN 相比,带有OR 子句的查询读取的行数更少,这增加了巨大的表和连接。
谁能帮我理解为什么会这样?
感谢您的宝贵时间。
【问题讨论】:
-
始终相同但结果不同?
-
@Marcus - 对不起,我不明白这个问题 - 如果你的意思是我每次都得到一致的结果集并且每次解析的行数也是一致的 - 那么答案是肯定的
-
@Marcus Adams - 我有一个复制粘贴错误 - 我已经纠正了。问题不在于不同的结果集 - 结果集是相同的 - 但 IN 与 OR 之间读取的行数不同 - 如果您无法重现它,请告诉我 - 我在服务器版本上:5.1跨度>
-
@MarcusAdams - 我想我很困惑,因为你写的这个评论
清楚地表明它不是来自简单的 SELECT,而不是来自你显示的查询 - 你看到我是从一个视图查询吗?你看到我的视图定义了吗?为了确保我是理智的,我创建了一个空数据库-运行了我提到的所有查询,然后运行了解释语句-没有额外的查询或选择语句-您是否尝试使用我给出的 sql 创建表? - 如果你这样做了,但你仍然觉得缺少一些东西 - 让我知道
-
对不起,我没有意识到您正在查询视图。我在下面提供了我的答案。