【发布时间】:2013-12-03 10:44:11
【问题描述】:
我有一个如下所示的数据库架构。
SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0;
SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0;
SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='TRADITIONAL,ALLOW_INVALID_DATES';
CREATE SCHEMA IF NOT EXISTS `mydb` DEFAULT CHARACTER SET latin1 COLLATE latin1_swedish_ci ;
USE `mydb` ;
-- -----------------------------------------------------
-- Table `mydb`.`parent`
-- -----------------------------------------------------
CREATE TABLE IF NOT EXISTS `mydb`.`parent` (
`id` INT NOT NULL ,
`data` VARCHAR(45) NULL ,
PRIMARY KEY (`id`) )
ENGINE = InnoDB;
-- -----------------------------------------------------
-- Table `mydb`.`OtherTable`
-- -----------------------------------------------------
CREATE TABLE IF NOT EXISTS `mydb`.`OtherTable` (
`id` INT NOT NULL ,
`data` VARCHAR(45) NULL ,
PRIMARY KEY (`id`) )
ENGINE = InnoDB;
-- -----------------------------------------------------
-- Table `mydb`.`parent_has_OtherTable`
-- -----------------------------------------------------
CREATE TABLE IF NOT EXISTS `mydb`.`parent_has_OtherTable` (
`parent_id` INT NOT NULL ,
`OtherTable_id` INT NOT NULL ,
PRIMARY KEY (`parent_id`, `OtherTable_id`) ,
INDEX `fk_parent_has_OtherTable_OtherTable1_idx` (`OtherTable_id` ASC) ,
INDEX `fk_parent_has_OtherTable_parent1_idx` (`parent_id` ASC) ,
CONSTRAINT `fk_parent_has_OtherTable_parent1`
FOREIGN KEY (`parent_id` )
REFERENCES `mydb`.`parent` (`id` )
ON DELETE NO ACTION
ON UPDATE NO ACTION,
CONSTRAINT `fk_parent_has_OtherTable_OtherTable1`
FOREIGN KEY (`OtherTable_id` )
REFERENCES `mydb`.`OtherTable` (`id` )
ON DELETE NO ACTION
ON UPDATE NO ACTION)
ENGINE = InnoDB;
-- -----------------------------------------------------
-- Table `mydb`.`child`
-- -----------------------------------------------------
CREATE TABLE IF NOT EXISTS `mydb`.`child` (
`parent_id` INT NOT NULL ,
`andAnotherTable_id` INT NOT NULL ,
`data` VARCHAR(45) NULL ,
PRIMARY KEY (`parent_id`) ,
CONSTRAINT `fk_child_parent1`
FOREIGN KEY (`parent_id` )
REFERENCES `mydb`.`parent` (`id` )
ON DELETE NO ACTION
ON UPDATE NO ACTION)
ENGINE = InnoDB;
SET SQL_MODE=@OLD_SQL_MODE;
SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS;
SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS;
我希望执行以下两个查询:
SELECT *
FROM child
INNER JOIN parent ON parent.id=child.parent_id
INNER JOIN parent_has_OtherTable ON parent_has_OtherTable.parent_id=parent.id
INNER JOIN OtherTable ON OtherTable.id=parent_has_OtherTable.OtherTable_id
WHERE child.parent_id=123
SELECT *
FROM child
INNER JOIN parent ON parent.id=child.parent_id
INNER JOIN parent_has_OtherTable ON parent_has_OtherTable.parent_id=parent.id
INNER JOIN OtherTable ON OtherTable.id=parent_has_OtherTable.OtherTable_id
WHERE OtherTable.id=123
我是否有任何理由需要在查询中包含parent 表(假设我不需要其中的任何数据),而是执行如下查询?我担心的是索引可能不再起作用,因为索引在parent 和parent_has_OtherTable 之间而不是child 和parent_has_OtherTable 之间。 PS。我还有其他类似于child 的表与parent 具有一对一的关系,因此我的架构就是这样的原因。
SELECT *
FROM child
INNER JOIN parent_has_OtherTable ON parent_has_OtherTable.parent_id=child.parent_id
INNER JOIN OtherTable ON OtherTable.id=parent_has_OtherTable.OtherTable_id
WHERE child.parent_id=123
SELECT *
FROM child
INNER JOIN parent_has_OtherTable ON parent_has_OtherTable.parent_id=child.parent_id
INNER JOIN OtherTable ON OtherTable.id=parent_has_OtherTable.OtherTable_id
WHERE OtherTable.id=123
mysql> EXPLAIN SELECT * FROM child INNER JOIN parent_has_OtherTable ON parent_has_OtherTable.parent_id=child.parent_id INNER JOIN OtherTable ON OtherTable.id=parent_has_OtherTable.OtherTable_id WHERE child.parent_id=1;
+----+-------------+-----------------------+-------+---------------------------------------------------------------------------------------+--------------------------------------+---------+-------+------+--------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-----------------------+-------+---------------------------------------------------------------------------------------+--------------------------------------+---------+-------+------+--------------------------------+
| 1 | SIMPLE | child | const | PRIMARY | PRIMARY | 4 | const | 1 | |
| 1 | SIMPLE | parent_has_OtherTable | ref | PRIMARY,fk_parent_has_OtherTable_OtherTable1_idx,fk_parent_has_OtherTable_parent1_idx | fk_parent_has_OtherTable_parent1_idx | 4 | const | 2 | Using index |
| 1 | SIMPLE | OtherTable | ALL | PRIMARY | NULL | NULL | NULL | 3 | Using where; Using join buffer |
+----+-------------+-----------------------+-------+---------------------------------------------------------------------------------------+--------------------------------------+---------+-------+------+--------------------------------+
3 rows in set (0.00 sec)
mysql> EXPLAIN SELECT * FROM child INNER JOIN parent_has_OtherTable ON parent_has_OtherTable.parent_id=child.parent_id INNER JOIN OtherTable ON OtherTable.id=parent_has_OtherTable.OtherTable_id WHERE OtherTable.id=1;
+----+-------------+-----------------------+-------+---------------------------------------------------------------------------------------+------------------------------------------+---------+-------+------+--------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-----------------------+-------+---------------------------------------------------------------------------------------+------------------------------------------+---------+-------+------+--------------------------------+
| 1 | SIMPLE | OtherTable | const | PRIMARY | PRIMARY | 4 | const | 1 | |
| 1 | SIMPLE | parent_has_OtherTable | ref | PRIMARY,fk_parent_has_OtherTable_OtherTable1_idx,fk_parent_has_OtherTable_parent1_idx | fk_parent_has_OtherTable_OtherTable1_idx | 4 | const | 2 | Using index |
| 1 | SIMPLE | child | ALL | PRIMARY | NULL | NULL | NULL | 3 | Using where; Using join buffer |
+----+-------------+-----------------------+-------+---------------------------------------------------------------------------------------+------------------------------------------+---------+-------+------+--------------------------------+
3 rows in set (0.00 sec)
mysql>
【问题讨论】:
标签: mysql sql indexing foreign-keys