web-dev-qa-db-ja.com

MySQLクエリ/句の実行順序

MySQLで句が実行される定義済みの順序は何ですか?一部は実行時に決定されますか?この順序は正しいですか?

  • FROM clause
  • WHERE clause
  • GROUP BY clause
  • HAVING clause
  • SELECT clause
  • ORDER BY clause
33
ericsicons

MySQLステートメントの実際の実行には少し注意が必要です。ただし、標準では、クエリ内の要素の解釈の順序が指定されています。 HAVINGGROUP BYSELECTの後に来る可能性があると思いますが、これは基本的に指定した順序です。

  • FROM
  • WHERE
  • SELECT
  • GROUP BY
  • HAVING
  • ORDER BY

これは、クエリの解析方法を理解するために重要です。たとえば、SELECTWHERE句の前に解析されるため、WHERE句のSELECTで定義された列エイリアスは使用できません。一方、このようなエイリアスはORDER BY句に含めることができます。

実際の実行に関しては、それは本当にオプティマイザーに任されています。例えば:

. . .
GROUP BY a, b, c
ORDER BY NULL

そして

. . .
GROUP BY a, b, c
ORDER BY a, b, c

両方ともORDER BYがまったく実行されないという効果があります。したがって、GROUP BYの後には実行されません(最初の場合、効果はGROUP BYおよび2番目の効果は、GROUP BYがすでに行っていること以外は何もしないことです)。

51
Gordon Linoff

これは、mysqlがどのように選択クエリを実行するかについての大まかなアイデアを得る方法です

DROP TABLE if exists new_table;

CREATE TABLE `new_table` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`testdecimal` decimal(6,2) DEFAULT NULL,
PRIMARY KEY (`id`));

INSERT INTO `new_table` (`testdecimal`) VALUES ('1234.45');
INSERT INTO `new_table` (`testdecimal`) VALUES ('1234.45');

set @mysqlorder := '';

select @mysqlorder := CONCAT(@mysqlorder," SELECT ") from new_table,(select @mysqlorder := CONCAT(@mysqlorder," FROM ")) tt
JOIN (select @mysqlorder := CONCAT(@mysqlorder," JOIN1 ")) t on ((select @mysqlorder := CONCAT(@mysqlorder," ON1 ")) or Rand() < 1)
JOIN (select @mysqlorder := CONCAT(@mysqlorder," JOIN2 ")) t2 on ((select @mysqlorder := CONCAT(@mysqlorder," ON2 ")) or Rand() < 1)
where ((select @mysqlorder := CONCAT(@mysqlorder," WHERE ")) or IF(new_table.testdecimal = 1234.45,true,false))
group by (select @mysqlorder := CONCAT(@mysqlorder," GROUPBY ")),id
having (select @mysqlorder := CONCAT(@mysqlorder," HAVING "))
order by (select @mysqlorder := CONCAT(@mysqlorder," ORDERBY "));

select @mysqlorder;

そして、これが上記のmysqlクエリの出力です。[〜#〜] select [〜#〜]クエリのmysql実行を理解できることを願っています:-

FROM JOIN1 JOIN2 WHERE ON2 ON1 ORDERBY GROUPBY SELECT WHERE ON2 ON1 ORDERBY GROUPBY SELECT HAVING HAVING