Movatterモバイル変換


[0]ホーム

URL:


yoku0825, profile picture
Uploaded byyoku0825
11,255 views

わかった気になるMySQL

2017/06/23 GMOテクノロジーブートキャンプ

Embed presentation

Downloaded 44 times
わかった 気になる MySQL〜SELECTステートメント編〜2017/06/23yoku0825の中の⼈GMOテクノロジーブートキャンプ
おことわりこの資料で述べられる⾒解はyoku0825の中の⼈のノリによるものであり、所属する組織または所属しない組織の意⾒を代表するわけがありませんこの資料を読んだりセッションを聞いたりしてもたぶんSQLを書けるようにはなりません1/105
つまり2/105
テキトーに聞いといてください3/105
MySQL触ったことある⼈︖4/105
MySQL できる ⼈︖5/105
MySQL知らない⼈︖6/105
MySQLより年下の⼈︖7/105
MySQL 1.0は1995年リリースらしいPast, Present and future ofMySQL and variants Part1: Ghosts of MySQL Past |Ramblings8/105
こんな画⾯触ったことある⼈︖9/105
こういうやつの⽅が好きな⼈︖10/105
MySQL好きな⼈︖11/105
三度の飯よりMySQLが好きな⼈︖12/105
MySQLやめるか煙草やめるかって⾔われたら13/105
⼈間やめる⼈︖14/105
\こんにちは/yoku0825の中の⼈@GMOメディアオラクれない-ポスグれない-マイエスキューエる-⽣息域Twitter: @yoku0825-Blog: ⽇々の覚書-MyNA ML: ⽇本MySQLユーザ会-MySQL Casual: Slack-15/105
普段やってること障害対応社内サポートデスクDBに特化した運⽤, 設計, ショット作業教育, 啓蒙活動技術研究16/105
障害対応開発陣はDBサーバーにSSHログインできないAP起因でMySQLがぶん回ったりするものを含むHWの交換はお任せ、OSを再セットアップしてもらってからが出番17/105
社内サポートデスク新しい開発環境のDBが欲しいんですけどAPサーバーが追加されたからGRANTしてほしいんだけどクエリー遅いんですけどこのサーバー撤去するんでDBどかして欲しいんですけどDBサーバー増やす︖ 減らす︖18/105
DBに特化した運⽤, 設計, ショット作業DBレイヤーのグランドデザインバックアップの記録, 保管-シャーディング-mikasafabric for MySQL + MySQL Router-必要リソースの⾒積もり-MySQL, Percona Server, MariaDB, Mroonga, Spider, PXC, ..-バージョンアップ戦略の策定-監視設計Seconds̲Behind̲Master, Max̲connections,Show̲processlist, ..-PMP for Cacti-テーブルサイズ, 権限変更検知, パラメーター変更検知, ロック競合, ..-19/105
DBに特化した運⽤, 設計, ショット作業フツーの ALTER TABLE でないオンラインスキーマ変更pt-osc-SET SESSION sql_log_bin= 0 からの ALTER TABLE .. ADD KEY ..ALGORITHM= INPLACE でRSU-スロークエリーチューニング件数だけは毎⽇通知-前⽇⽐でハネたら anemoeater でドリルダウン-メンテのついでにマイナーバージョンアップとかメジャーバージョンアップとか20/105
教育, 啓蒙活動新⼊社員研修社内勉強会おもむろにPRやIssueに出現してマサカリを投げて去る21/105
技術研究MySQL 8.0エコシステム各種の検証⼿抜き監査ログクライアントmikasafabric for MySQL何故かDocker全般22/105
MySQL #とは世界でもっとも普及している、オープン ソース データベースhttps://www.mysql.com/jp/23/105
MySQL #とは永続化可能なサーバーまたいでアクセスできる排他・共有ロック機能付きのグローバル変数のすごいやつ異論は認めるMySQLおじさんの逆襲24/105
置いといて25/105
今⽇は基礎としてSELECTステートメントの話(だけ)をします26/105
簡素化したSELECTステートメントSELECTcolumn1, column2, ..FROMtable1WHEREcolumn1 = '..'ORDER BYcolumn2;27/105
肩慣らし28/105
肩慣らし何のエラーが出る︖SEECT -- Invalid Syntaxnonexistent_column_in_select_listFROMnonexistent_tableWHEREnonexistent_column_in_where_clause = '..'ORDER BYnonexistent_column_in_orderby_clause;29/105
答えMySQL error code 1064 (ER̲PARSE̲ERROR): %s nearʻ%-.80sʼ at line %dERROR 1064 (42000): You have an error in your SQL syntax; checkthe manual that corresponds to your MySQL server version for the right syntax to use near '..'30/105
肩慣らし何のエラーが出る︖SELECTnonexistent_column_in_select_listFROMnonexistent_tableWHEREnonexistent_column_in_where_clause = '..'ORDER BYnonexistent_column_in_orderby_clause;31/105
答えMySQL error code 1146 (ER̲NO̲SUCH̲TABLE): Tableʻ%-.192s.%-.192sʼ doesnʼt existERROR 1146 (42S02): Table 'test.nonexistent_table' doesn't exist32/105
肩慣らし何のエラーが出る︖SELECTnonexistent_column_in_select_listFROMtable1WHEREnonexistent_column_in_where_clause = '..'ORDER BYnonexistent_column_in_orderby_clause;33/105
答えMySQL error code 1054 (ER̲BAD̲FIELD̲ERROR):Unknown column ʻ%-.192sʼ in ʻ%-.192sʼERROR 1054 (42S22): Unknown column 'nonexistent_column_in_select_list' in 'field list'34/105
肩慣らし何のエラーが出る︖SELECTcolumn1FROMtable1WHEREnonexistent_column_in_where_clause = '..'ORDER BYnonexistent_column_in_orderby_clause;35/105
答えMySQL error code 1054 (ER̲BAD̲FIELD̲ERROR):Unknown column ʻ%-.192sʼ in ʻ%-.192sʼERROR 1054 (42S22): Unknown column 'nonexistent_column_in_where_clause' in 'where clause'36/105
肩慣らし何のエラーが出る︖SELECTcolumn1FROMtable1WHEREcolumn1 = '..'ORDER BYnonexistent_column_in_orderby_clause;37/105
答えMySQL error code 1054 (ER̲BAD̲FIELD̲ERROR):Unknown column ʻ%-.192sʼ in ʻ%-.192sʼERROR 1054 (42S22): Unknown column 'nonexistent_column_in_orderby_clause' in 'order clause'38/105
ER̲BAD̲FIELD̲ERRORMySQL error code 1054 (ER̲BAD̲FIELD̲ERROR):Unknown column ʻ%-.192sʼ in ʻ%-.192sʼERROR 1054 (42S22): Unknown column 'nonexistent_column_in_select_list' in 'field list'ERROR 1054 (42S22): Unknown column 'nonexistent_column_in_where_clause' in 'where clause'ERROR 1054 (42S22): Unknown column 'nonexistent_column_in_orderby_clause' in 'order clause'39/105
取り敢えずわかることシンタックスエラーが⼀番強いパースできないとどれがオブジェクトでどれがキーワードかわからない-FROM句だけ特別っぽいたぶん、対象オブジェクトを確定してアクセス権限のチェックしないといけないから-他は頭から読んでる︖SQLパーザーは先頭から再帰的に構⽂解析している-40/105
シンプルなSELECTにも⾊々ある41/105
ストアドファンクションとか使った複雑なSELECTにはもっと⾊々(ry42/105
SELECTステートメントSELECT[ALL | DISTINCT | DISTINCTROW ][HIGH_PRIORITY][STRAIGHT_JOIN][SQL_SMALL_RESULT] [SQL_BIG_RESULT] [SQL_BUFFER_RESULT][SQL_CACHE | SQL_NO_CACHE] [SQL_CALC_FOUND_ROWS]select_expr [, select_expr ...][FROM table_references[PARTITION partition_list][WHERE where_condition][GROUP BY {col_name | expr | position}[ASC | DESC], ... [WITH ROLLUP]][HAVING where_condition][ORDER BY {col_name | expr | position}[ASC | DESC], ...][LIMIT {[offset,] row_count | row_count OFFSET offset}][PROCEDURE procedure_name(argument_list)][INTO OUTFILE 'file_name'[CHARACTER SET charset_name]export_options| INTO DUMPFILE 'file_name'| INTO var_name [, var_name]][FOR UPDATE | LOCK IN SHARE MODE]]https://dev.mysql.com/doc/refman/5.7/en/select.html43/105
シンタックスこのへんはフツーに使うだろうからやらないDISTINCT-STRAIGHT̲JOIN-LIMIT-INTO OUTFILE-[FOR UPDATE | LOCK IN SHARE MODE]-44/105
シンタックス(1)select_exprselect̲listとも-雑に⾔うと「カラム名を列挙するとこ」-exprの名が⽰すように、式も記述できる-最低1つ必要-45/105
MySQLのbool評価式真なら1, 偽なら0, UNKNOWNならNULLが返るmysql80 5> SELECT DAYOFWEEK('2017/06/23') = 6;+-----------------------------+| DAYOFWEEK('2017/06/23') = 6 |+-----------------------------+| 1 |+-----------------------------+1 row in set (0.03 sec)mysql80 5> SELECT DAYOFWEEK('2017/06/23') = 5;+-----------------------------+| DAYOFWEEK('2017/06/23') = 5 |+-----------------------------+| 0 |+-----------------------------+1 row in set (0.01 sec)46/105
こんな結果セットがあった時にmysql80 5> WITH RECURSIVE june AS (-> SELECT CAST('2017/06/01' AS DATE) AS dt-> UNION ALL-> SELECT DATE_ADD(dt, INTERVAL 1 DAY) AS dt FROM june WHERE dt < '2017/06/30')-> SELECT * FROM june;+------------+| dt |+------------+| 2017-06-01 || 2017-06-02 || 2017-06-03 |..| 2017-06-28 || 2017-06-29 || 2017-06-30 |+------------+30 rows in set (0.00 sec)47/105
こんな キモい こともできる1または0だからSUMがきくmysql80 5> WITH RECURSIVE june AS (-> SELECT CAST('2017/06/01' AS DATE) AS dt-> UNION ALL-> SELECT DATE_ADD(dt, INTERVAL 1 DAY) AS dt FROM june WHERE dt < '2017/06/30')-> SELECT SUM(WEEKDAY(dt) IN (5, 6)) AS not_working, SUM(WEEKDAY(dt) NOT IN (5, 6)) AS working FROM june;+-------------+---------+| not_working | working |+-------------+---------+| 8 | 22 |+-------------+---------+1 row in set (0.01 sec)48/105
SELECTステートメントSELECT[ALL | DISTINCT | DISTINCTROW ][HIGH_PRIORITY][STRAIGHT_JOIN][SQL_SMALL_RESULT] [SQL_BIG_RESULT] [SQL_BUFFER_RESULT][SQL_CACHE | SQL_NO_CACHE] [SQL_CALC_FOUND_ROWS]select_expr [, select_expr ...][FROM table_references[PARTITION partition_list][WHERE where_condition][GROUP BY {col_name | expr | position}[ASC | DESC], ... [WITH ROLLUP]][HAVING where_condition][ORDER BY {col_name | expr | position}[ASC | DESC], ...][LIMIT {[offset,] row_count | row_count OFFSET offset}][PROCEDURE procedure_name(argument_list)][INTO OUTFILE 'file_name'[CHARACTER SET charset_name]export_options| INTO DUMPFILE 'file_name'| INTO var_name [, var_name]][FOR UPDATE | LOCK IN SHARE MODE]]49/105
シンタックス(2)table_referencesテーブルじゃなくてテーブルリファレンス、なのが楽しいところ-JOINした結果やサブクエリーなど、割とあらゆるSELECTの出⼒結果がそのままテーブルリファレンスになれる-特別なキーワードとして FROM dual がある。FROM 句⾃体の省略もできる-50/105
こんな⼊れ⼦もmysql80 5> SELECT * FROM (-> SELECT * FROM (-> SELECT * FROM (-> SELECT * FROM (-> SELECT * FROM (-> SELECT NOW()-> ) AS t1-> ) AS t2-> ) AS t3-> ) AS t4-> ) AS t5;+---------------------+| NOW() |+---------------------+| 2017-06-21 19:49:16 |+---------------------+1 row in set (0.00 sec)51/105
SELECTステートメントSELECT[ALL | DISTINCT | DISTINCTROW ][HIGH_PRIORITY][STRAIGHT_JOIN][SQL_SMALL_RESULT] [SQL_BIG_RESULT] [SQL_BUFFER_RESULT][SQL_CACHE | SQL_NO_CACHE] [SQL_CALC_FOUND_ROWS]select_expr [, select_expr ...][FROM table_references[PARTITION partition_list][WHERE where_condition][GROUP BY {col_name | expr | position}[ASC | DESC], ... [WITH ROLLUP]][HAVING where_condition][ORDER BY {col_name | expr | position}[ASC | DESC], ...][LIMIT {[offset,] row_count | row_count OFFSET offset}][PROCEDURE procedure_name(argument_list)][INTO OUTFILE 'file_name'[CHARACTER SET charset_name]export_options| INTO DUMPFILE 'file_name'| INTO var_name [, var_name]][FOR UPDATE | LOCK IN SHARE MODE]]52/105
シンタックス(3)where_conditionWHEREとHAVINGで指定する-真偽値(ところによりNULL)を返す式-実は定数でもイケる-MySQLでは0が偽、0以外が真、NULLがUNKNOWNただしFALSEは0のシノニム、TRUEは1のシノニム-WHERE 1 って書くと全ての⾏で真になる-53/105
知ってると⾯⽩いmysql80 5> SELECT * FROM t1;+-----+------+| num | val |+-----+------+| 1 | one || 2 | two |+-----+------+2 rows in set (0.01 sec)mysql80 5> SELECT * FROM t1 WHERE num;+-----+------+| num | val |+-----+------+| 1 | one | <-- numは0じゃないので真| 2 | two | <-- numは0じゃないので真+-----+------+2 rows in set (0.00 sec)54/105
知ってると⾯⽩いmysql80 5> SELECT * FROM t1 WHERE num = TRUE;+-----+------+| num | val |+-----+------+| 1 | one | <-- TRUEは1だからnum = 1+-----+------+1 row in set (0.00 sec)mysql80 24> SELECT * FROM t1 WHERE num IS TRUE;+-----+------+| num | val |+-----+------+| 1 | one | <-- 1 IS TRUE => 真| 2 | two | <-- 2 IS TRUE => 真+-----+------+2 rows in set (0.02 sec)55/105
NULLに対する演算(1)NULL + 1NULL - 1NULL * 1NULL / 1CONCAT(NULL, 'ぽ', 'ガッ')56/105
NULLに対する演算(1)mysql80 25> SELECT NULL + 1, NULL - 1, NULL * 1, NULL / 1, CONCAT(NULL, 'ぽ', 'ガッ')G*************************** 1. row ***************************NULL + 1: NULLNULL - 1: NULLNULL * 1: NULLNULL / 1: NULLCONCAT(NULL, 'ぽ', 'ガッ'): NULL1 row in set (0.00 sec)57/105
NULLに対する演算(2)NULL AND NULLNULL AND TRUENULL AND FALSENULL OR NULLNULL OR TRUENULL OR FALSE58/105
NULLに対する演算(2)mysql80 25> SELECT NULL AND NULL, NULL AND TRUE, NULL AND FALSE, NULL OR NULL, NULL OR TRUE, NULL OR FALSEG*************************** 1. row ***************************NULL AND NULL: NULLNULL AND TRUE: NULLNULL AND FALSE: 0NULL OR NULL: NULLNULL OR TRUE: 1NULL OR FALSE: NULL1 row in set (0.00 sec)59/105
NOT NULL推奨ある整数AはA = 1 または A <> 1-A == 1のテストとA == 0のテストを書けば境界値テストでカバーできる-ある整数型のNULLABLEなカラムに格納された値BはB = 1 または B <> 1 または B IS NULLである-B == 1のテストとB == 0とdefined(B) == falseの3つのテストを書かないといけない-60/105
テストケースの増⼤WHERE句にカラムを並べたとしてカラムの数 NOT NULL 境界値の数1 o 2^1=22 o 2^2=43 o 2^3=81 x 3^1=32 x 3^2=93 x 3^3=2761/105
NOTNULL推奨62/105
(余談) NULLABLEは伝播するNULLに対する演算をしてもNULLが返らない演算をNULLセーフな演算と呼ぶたとえば IS NULL 演算⼦はNULLセーフ演算⼦-NULLに対する非NULLセーフな演算の結果はNULLいくつかのカラムがNOT NULLであったとしても、それとNULLABLEなカラムの値を非NULLセーフな関数で演算してしまったらその結果はNULLABLEひとつのNULLABLEなカラムと演算する可能性のあるカラム全てに三値論理を適⽤する︖63/105
閑話休題64/105
SELECTステートメントSELECT[ALL | DISTINCT | DISTINCTROW ][HIGH_PRIORITY][STRAIGHT_JOIN][SQL_SMALL_RESULT] [SQL_BIG_RESULT] [SQL_BUFFER_RESULT][SQL_CACHE | SQL_NO_CACHE] [SQL_CALC_FOUND_ROWS]select_expr [, select_expr ...][FROM table_references[PARTITION partition_list][WHERE where_condition][GROUP BY {col_name | expr | position}[ASC | DESC], ... [WITH ROLLUP]][HAVING where_condition][ORDER BY {col_name | expr | position}[ASC | DESC], ...][LIMIT {[offset,] row_count | row_count OFFSET offset}][PROCEDURE procedure_name(argument_list)][INTO OUTFILE 'file_name'[CHARACTER SET charset_name]export_options| INTO DUMPFILE 'file_name'| INTO var_name [, var_name]][FOR UPDATE | LOCK IN SHARE MODE]]65/105
シンタックス(4)col_name | expr | positionGROUP BY や ORDER BY で指定するやつ-カラム名、評価式、select̲list内のオフセット(1オリジン)で指定できる-ORDER BY RAND() なんてのは1⾏ごとに RAND() が⾛って、その結果(0から1までのDOUBLE)でソートするからランダムな結果セットが返る-ORDER BY NULL なんてキーワードもある-expr の⽰す通り、値を返す式でもイケる-66/105
⾶び道具っぽいORDER BY指定mysql80 5> SELECT * FROM t1;+-----+-------+| num | val |+-----+-------+| 1 | one || 2 | two || 3 | three || 4 | four || 5 | five |+-----+-------+5 rows in set (0.00 sec)mysql80 5> SELECT num, val FROM t1 ORDER BY 2 DESC; -- select_listの2要素目=valのDESCソート+-----+-------+| num | val |+-----+-------+| 2 | two || 3 | three || 1 | one || 4 | four || 5 | five |+-----+-------+5 rows in set (0.00 sec)67/105
⾶び道具ORDER BYその2mysql80 23> SELECT * FROM t1 ORDER BY FIELD (num, 1, 4, 5, 3, 2);+-----+-------+| num | val |+-----+-------+| 1 | one || 4 | four || 5 | five || 3 | three || 2 | two |+-----+-------+5 rows in set (0.03 sec)mysql80 23> SELECT *, FIELD (num, 1, 4, 5, 3, 2) AS sort_expr FROM t1 ORDER BY FIELD (num, 1, 4, 5, 3, 2);+-----+-------+-----------+| num | val | sort_expr |+-----+-------+-----------+| 1 | one | 1 || 4 | four | 2 || 5 | five | 3 || 3 | three | 4 || 2 | two | 5 |+-----+-------+-----------+5 rows in set (0.00 sec)68/105
NULLABLEなカラムのソートmysql80 24> SELECT * FROM t1 ORDER BY num;+------+------+| num | val |+------+------+| NULL | NULL || 1 | one || 2 | two |+------+------+3 rows in set (0.00 sec)mysql80 24> SELECT * FROM t1 ORDER BY num DESC;+------+------+| num | val |+------+------+| 2 | two || 1 | one || NULL | NULL |+------+------+3 rows in set (0.00 sec)69/105
SELECTステートメントSELECT[ALL | DISTINCT | DISTINCTROW ][HIGH_PRIORITY][STRAIGHT_JOIN][SQL_SMALL_RESULT] [SQL_BIG_RESULT] [SQL_BUFFER_RESULT][SQL_CACHE | SQL_NO_CACHE] [SQL_CALC_FOUND_ROWS]select_expr [, select_expr ...][FROM table_references[PARTITION partition_list][WHERE where_condition][GROUP BY {col_name | expr | position}[ASC | DESC], ... [WITH ROLLUP]][HAVING where_condition][ORDER BY {col_name | expr | position}[ASC | DESC], ...][LIMIT {[offset,] row_count | row_count OFFSET offset}][PROCEDURE procedure_name(argument_list)][INTO OUTFILE 'file_name'[CHARACTER SET charset_name]export_options| INTO DUMPFILE 'file_name'| INTO var_name [, var_name]][FOR UPDATE | LOCK IN SHARE MODE]]70/105
クエリーキャッシュ関連[SQL̲CACHE|SQL̲NO̲CACHE]クエリー単位でクエリーキャッシュの有効/無効を切り替えられるquery̲cache̲type 指定なし SQL̲CACHE SQL̲NO̲CACHE0(DISABLE) x x x1(ENABLE) o o x2(DEMAND) x o x71/105
笑えるコード653 static bool has_no_cache_directive(const char *sql, uint offset,654 size_t query_length)655 {..671 if (my_toupper(system_charset_info, sql[i]) == 'S' &&672 my_toupper(system_charset_info, sql[i+1]) == 'Q' &&673 my_toupper(system_charset_info, sql[i+2]) == 'L' &&674 my_toupper(system_charset_info, sql[i+3]) == '_' &&675 my_toupper(system_charset_info, sql[i+4]) == 'N' &&676 my_toupper(system_charset_info, sql[i+5]) == 'O' &&677 my_toupper(system_charset_info, sql[i+6]) == '_' &&678 my_toupper(system_charset_info, sql[i+7]) == 'C' &&679 my_toupper(system_charset_info, sql[i+8]) == 'A' &&680 my_toupper(system_charset_info, sql[i+9]) == 'C' &&681 my_toupper(system_charset_info, sql[i+10]) == 'H' &&682 my_toupper(system_charset_info, sql[i+11]) == 'E' &&683 my_isspace(system_charset_info, sql[i+12]))684 return true;mysql-5.7.18/sql/sql̲cache.cc72/105
過去の遺物[HIGH̲PRIORITY][SQL̲SMALL̲RESULT][SQL̲BIG̲RESULT][SQL̲BUFFER̲RESULT][PROCEDURE analyse()]73/105
闇なやつ[SQL̲CALC̲FOUND̲ROWS]ORDER BY .. LIMIT .. のbreakを無効にする代わりに、COUNT(*) も⼀緒に取得する取得した COUNT(*) は SELECT FOUND_ROWS() でアクセス可能-2回テーブルスキャンするよりは速いけど、 ORDER BY ..LIMIT .. の早抜けできなくなるので遅い74/105
闇なやつmysql80 7397205> SELECT * FROM city ORDER BY population DESC LIMIT 10;..10 rows in set (0.01 sec)mysql80 7397205> SELECT FOUND_ROWS();+--------------+| FOUND_ROWS() |+--------------+| 10 |+--------------+1 row in set (0.00 sec)mysql80 7397205> SELECT sql_calc_found_rows * FROM city ORDER BY population DESCLIMIT 10;..10 rows in set (0.00 sec)mysql80 7397205> SELECT FOUND_ROWS();+--------------+| FOUND_ROWS() |+--------------+| 4079 |+--------------+1 row in set (0.00 sec)75/105
5.6とそれ以降ではパーティションがテーブルリファレンスに指定できるFROM t1 PARTITION (p1, p2)特定のパーティションだけをあたかもテーブルのようにアクセスできる上⼿く使うとWHERE句をいっこかっ⾶ばせたり、不要なパーティションへのアクセスをさせないように指定できる(実際に1つのパーティションアクセスだけで完結するクエリーでも、オプティマイザーがそれを確定できない場合は全パーティションアクセスになる、など)76/105
パーティション指定アクセスmysql80 22> SHOW CREATE TABLE t2G*************************** 1. row ***************************Table: t2Create Table: CREATE TABLE `t2` (`dt` date NOT NULL,`val` varchar(32) COLLATE utf8mb4_ja_0900_as_cs DEFAULT NULL,PRIMARY KEY (`dt`)) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_ja_0900_as_cs/*!50100 PARTITION BY LIST (month(dt) mod 2)(PARTITION p_odd VALUES IN (1) ENGINE = InnoDB,PARTITION p_even VALUES IN (0) ENGINE = InnoDB) */1 row in set (0.00 sec)$ ll /usr/mysql/8.0.1/data/d1/t2*-rw-r----- 1 yoku0825 yoku0825 131072 Jun 22 11:39 /usr/mysql/8.0.1/data/d1/t2#P#p_even.ibd-rw-r----- 1 yoku0825 yoku0825 131072 Jun 22 11:39 /usr/mysql/8.0.1/data/d1/t2#P#p_odd.ibd77/105
パーティション指定アクセスmysql80 22> EXPLAIN SELECT * FROM t2 WHERE dt BETWEEN '2017/06/01' AND '2017/06/30';+----+-------------+-------+--------------+-------+---------------+---------+---------+------+------+----------+-------------+| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |+----+-------------+-------+--------------+-------+---------------+---------+---------+------+------+----------+-------------+| 1 | SIMPLE | t2 | p_odd,p_even | range | PRIMARY | PRIMARY | 3 | NULL | 5 | 100.00 | Using where |+----+-------------+-------+--------------+-------+---------------+---------+---------+------+------+----------+-------------+1 row in set, 1 warning (0.04 sec)mysql80 22> EXPLAIN SELECT * FROM t2 PARTITION (p_even) WHERE dt BETWEEN '2017/06/01' AND '2017/06/30';+----+-------------+-------+------------+-------+---------------+---------+---------+------+------+----------+-------------+| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |+----+-------------+-------+------------+-------+---------------+---------+---------+------+------+----------+-------------+| 1 | SIMPLE | t2 | p_even | range | PRIMARY | PRIMARY | 3 | NULL | 5 | 100.00 | Using where |+----+-------------+-------+------------+-------+---------------+---------+---------+------+------+----------+-------------+1 row in set, 1 warning (0.00 sec)78/105
SELECT処理のイメージイメージなのでちょくちょく 嘘79/105
SELECT処理のイメージ(1)まず結果セットのベースになるFROM句の要素全体に注目ただし相関サブクエリー以外のサブクエリーはこれに先⽴って解決される-Whole Table80/105
SELECT処理のイメージ(2)WHERE句に従ってフィルタリングWhole TableFiltered Set81/105
SELECT処理のイメージ(3)ソートしたり集約したりWhole TableFiltered SetSorted Set82/105
SELECT処理のイメージ(4)結果セットに必要な列だけをバッファに詰めてできあがりWhole TableFiltered SetSorted Set83/105
GROUP BY, HAVING, ORDER BY, LIMITWHEREで件数を絞り込んだあとにGROUP BYで集約した後にHAVINGでフィルターしてORDER BYで並べ替えてからLIMITで指定した⾏数だけ返す84/105
もうちょっと細かく︖85/105
よく使う図InnoDB APIHandler APIExecutorOptimizerParserMySQL Protocol HS ProtocolHS Pluginmemcached ProtocolInnoDB MemcachedHTTP/MySQL X86/105
クエリーのライフサイクルConnection HandlingParserOptimizerExecutorHandlerStorage Engine87/105
Connection Handlingソケット, ポートからの接続を待ち受ける接続があったらclone(またはスレッドキャッシュから取り出してディスパッチ)⼀次認証88/105
ParserMySQLプロトコルのパースSQL構⽂のパース⼆次認証(データベース, テーブル単位のアクセス権限チェック)クエリーキャッシュ処理ジェネラルログ89/105
Optimizer統計情報の取得(Storage Engine APIを叩いてるっぽい)クエリーの書き換えを含めた実⾏計画の決定90/105
Executorオプティマイザーから渡された実⾏計画の通りにHandlerを叩くHandlerから戻ってきた結果を使って実⾏計画の残りを実⾏Using where; Using filesort; Using temporary; はコイツが頑張ってる証拠-スローログ, バイナリーログ91/105
Handlerストレージエンジンの抽象化レイヤーあんまり意識することはない92/105
Storage Engine実際にデータを格納するレイヤープラガブルアーキテクチャーなので、ほとんどの機能はこのレイヤーで実装されているストレージエンジンごとにトランザクション対応が違うとか-ストレージエンジンごとにロック粒度が違うとか-ストレージエンジンごとにバッファが違うとか-93/105
え︖ もっと細かく︖94/105
SELECTステートメントの⼀⽣(1)3306ポートへのアクセスがmysqld̲mainによって捕捉され、⼦スレッドが割り当てられるhandle̲connectionからdo̲commandを経てdispatch̲commandへ、ここでユーザー認証dispatch̲commandでMySQLプロトコルをパースし、COM̲QUERYパケットとしてSQLパーサーにかけられるmysql̲parseを通ってparse̲sqlからMYSQLparseを呼ぶMYSQLparseの中でthd->lexに⾊々⼊るmysql̲parseまで戻ってここでジェネラルログ出⼒Max Query per Hourの判定が⼊ってパスワードがEXPIREされてないかの判定が⼊ってやっとmysql̲execute̲commandに⾶ぶ 95/105
SELECTステートメントの⼀⽣(2)read̲onlyオプションの判定が⼊ったりしたあとlex->sql̲commandで振り分け処理がされつつselect̲precheckが呼ばれてアカウントの権限が評価されexecute̲sqlcom̲selectにわたり、MAX̲EXECUTION̲TIMEのタイマーがセットされてopen̲tables̲for̲queryでテーブルキャッシュを開きsql̲select.ccのhandle̲queryに⾏ってオブジェクト名の評価がされquery̲cache.store̲queryを呼びSELECT̲LEX::optimizeからのJOIN::optimize呼び出し、ここからがオプティマイザー96/105
SELECTステートメントの⼀⽣(3)可能であればOUTER JOIN ⇒ INNER JOINの書き換えとか結合条件をWHERE句に移動する処理とかSEMIJOINならここでビットマップインデックスを作るsql̲mode=ONLY̲FULL̲GROUP̲BYの場合の評価はここパーティションプルーニングが効く場合はここでプルーニングアクセスプランを評価・確定させてJOIN::execからdo̲selectに渡って最終的にhandlerからha̲innobaseクラスにわたる97/105
SELECTステートメントの⼀⽣(4)⾏のフェッチが終わったらソートしたりフィルタリングしたり⾊々してからclose̲thread̲tablesでテンポラリーテーブル消したりclose̲thread̲tableでテーブル閉じてテーブルキャッシュに⼊れてmdl̲context.release̲transactional̲locksでメタデータロックを解放して使ったオブジェクトを⾊々freeしてQuery̲result̲send::send̲dataで結果セットを返す98/105
諸元SQLパーサーsql/sql̲yacc.yy, sql/sql̲yacc.ccエグゼキューターsql/sql̲executor.cc, sql/sql̲select.cc汎⽤ユーティリティーsql/sql̲class.ccInnoDBストレージエンジンstorage/innobase/99/105
え、まだまだ⾜りない︖100/105
↑やら↑101/105
↓ない↓102/105
まとめ︖普段何気なく使っているMySQLもアプリケーション⾊んな内部実装があって、得意なことがあったり苦⼿なことがあったりそれをユーザーに意識させないためにSQLというレイヤーがあるのでそれより下を勉強するのはなかなか⼤変世界は広くて、そういう世界で戦っているエンジニアもいるにはいる103/105
まとめ︖困った時はいつでもどうぞMyNA ML: ⽇本MySQLユーザ会-MySQL Casual: Slack-おじさんズ welcome you!104/105
Questionsand/orSuggestions?105/105

Recommended

PDF
今からでも遅くないDBマイグレーション - Flyway と SchemaSpy の紹介 -
PDF
Amazon Cognito使って認証したい?それならSpring Security使いましょう!
PDF
ドメインオブジェクトの見つけ方・作り方・育て方
PDF
なかったらINSERTしたいし、あるならロック取りたいやん?
PDF
Mavenの真実とウソ
PDF
SQLアンチパターン 幻の第26章「とりあえず削除フラグ」
PDF
Dockerfileを改善するためのBest Practice 2019年版
PDF
オブジェクト指向できていますか?
PDF
MySQL 5.7にやられないためにおぼえておいてほしいこと
PDF
Java EE から Quarkus による開発への移行について
PDF
ドメイン駆動設計のためのオブジェクト指向入門
PPTX
ぱぱっと理解するSpring Cloudの基本
PDF
Tackling Complexity
PDF
イミュータブルデータモデル(世代編)
PDF
ドメイン駆動設計 失敗したことと成功したこと
PDF
例外設計における大罪
PDF
SQL大量発行処理をいかにして高速化するか
PPTX
今こそ知りたいSpring Web(Spring Fest 2020講演資料)
PPTX
RLSを用いたマルチテナント実装 for Django
PDF
Serverless時代のJavaについて
PDF
serviceクラスをやめようサブクラスを使おう
PDF
MySQL 5.7の罠があなたを狙っている
PDF
文字コードに起因する脆弱性とその対策(増補版)
PPTX
Spring Boot ユーザの方のための Quarkus 入門
PDF
イミュータブルデータモデルの極意
PDF
OpenAPI 3.0でmicroserviceのAPI定義を試みてハマった話
PDF
Javaのログ出力: 道具と考え方
PPTX
世界一わかりやすいClean Architecture
PPT
今年こそ始めたい!SQL超入門 MIRACLE Linux Meetup版 0620
PPT
今年こそ始めたい!SQL超入門 セミナー資料 2024年5月22日 富士通クラウドミートアップ

More Related Content

PDF
今からでも遅くないDBマイグレーション - Flyway と SchemaSpy の紹介 -
PDF
Amazon Cognito使って認証したい?それならSpring Security使いましょう!
PDF
ドメインオブジェクトの見つけ方・作り方・育て方
PDF
なかったらINSERTしたいし、あるならロック取りたいやん?
PDF
Mavenの真実とウソ
PDF
SQLアンチパターン 幻の第26章「とりあえず削除フラグ」
PDF
Dockerfileを改善するためのBest Practice 2019年版
PDF
オブジェクト指向できていますか?
今からでも遅くないDBマイグレーション - Flyway と SchemaSpy の紹介 -
Amazon Cognito使って認証したい?それならSpring Security使いましょう!
ドメインオブジェクトの見つけ方・作り方・育て方
なかったらINSERTしたいし、あるならロック取りたいやん?
Mavenの真実とウソ
SQLアンチパターン 幻の第26章「とりあえず削除フラグ」
Dockerfileを改善するためのBest Practice 2019年版
オブジェクト指向できていますか?

What's hot

PDF
MySQL 5.7にやられないためにおぼえておいてほしいこと
PDF
Java EE から Quarkus による開発への移行について
PDF
ドメイン駆動設計のためのオブジェクト指向入門
PPTX
ぱぱっと理解するSpring Cloudの基本
PDF
Tackling Complexity
PDF
イミュータブルデータモデル(世代編)
PDF
ドメイン駆動設計 失敗したことと成功したこと
PDF
例外設計における大罪
PDF
SQL大量発行処理をいかにして高速化するか
PPTX
今こそ知りたいSpring Web(Spring Fest 2020講演資料)
PPTX
RLSを用いたマルチテナント実装 for Django
PDF
Serverless時代のJavaについて
PDF
serviceクラスをやめようサブクラスを使おう
PDF
MySQL 5.7の罠があなたを狙っている
PDF
文字コードに起因する脆弱性とその対策(増補版)
PPTX
Spring Boot ユーザの方のための Quarkus 入門
PDF
イミュータブルデータモデルの極意
PDF
OpenAPI 3.0でmicroserviceのAPI定義を試みてハマった話
PDF
Javaのログ出力: 道具と考え方
PPTX
世界一わかりやすいClean Architecture
MySQL 5.7にやられないためにおぼえておいてほしいこと
Java EE から Quarkus による開発への移行について
ドメイン駆動設計のためのオブジェクト指向入門
ぱぱっと理解するSpring Cloudの基本
Tackling Complexity
イミュータブルデータモデル(世代編)
ドメイン駆動設計 失敗したことと成功したこと
例外設計における大罪
SQL大量発行処理をいかにして高速化するか
今こそ知りたいSpring Web(Spring Fest 2020講演資料)
RLSを用いたマルチテナント実装 for Django
Serverless時代のJavaについて
serviceクラスをやめようサブクラスを使おう
MySQL 5.7の罠があなたを狙っている
文字コードに起因する脆弱性とその対策(増補版)
Spring Boot ユーザの方のための Quarkus 入門
イミュータブルデータモデルの極意
OpenAPI 3.0でmicroserviceのAPI定義を試みてハマった話
Javaのログ出力: 道具と考え方
世界一わかりやすいClean Architecture

Similar to わかった気になるMySQL

PPT
今年こそ始めたい!SQL超入門 MIRACLE Linux Meetup版 0620
PPT
今年こそ始めたい!SQL超入門 セミナー資料 2024年5月22日 富士通クラウドミートアップ
PDF
introduction_to_only_SQL
PDF
MySQL 5.5 Update #denatech
PDF
OSS-DB Silver ポイント解説セミナー ~SQL編~ (PostgreSQL9.0)
PPTX
SQL Serverの関数を一覧でマスターしよう
 
PPTX
Sql learning2
PDF
2018年度 若手技術者向け講座 実行計画
 
PDF
PostgreSQL SQLチューニング入門 実践編(pgcon14j)
PPTX
T sql 振り返り
PPT
SQLチューニング勉強会資料
PDF
Oracleの実行計画を読んでみよう! #dbts2017
PPT
Online schema change in mysql casual #1(2010/12/11)
PPT
Online schema change in mysql casual #1(2010/12/11)
PDF
データサイエンス勉強会(SQL)
PDF
2018年度 若手技術者向け講座 インデックス
 
PDF
MySQLステータスモニタリング
PDF
PostgreSQLの実行計画を読み解こう(OSC2015 Spring/Tokyo)
PDF
MySQL 5.7が魅せる新しい運用の形
PPT
20090107 Postgre Sqlチューニング(Sql編)
今年こそ始めたい!SQL超入門 MIRACLE Linux Meetup版 0620
今年こそ始めたい!SQL超入門 セミナー資料 2024年5月22日 富士通クラウドミートアップ
introduction_to_only_SQL
MySQL 5.5 Update #denatech
OSS-DB Silver ポイント解説セミナー ~SQL編~ (PostgreSQL9.0)
SQL Serverの関数を一覧でマスターしよう
 
Sql learning2
2018年度 若手技術者向け講座 実行計画
 
PostgreSQL SQLチューニング入門 実践編(pgcon14j)
T sql 振り返り
SQLチューニング勉強会資料
Oracleの実行計画を読んでみよう! #dbts2017
Online schema change in mysql casual #1(2010/12/11)
Online schema change in mysql casual #1(2010/12/11)
データサイエンス勉強会(SQL)
2018年度 若手技術者向け講座 インデックス
 
MySQLステータスモニタリング
PostgreSQLの実行計画を読み解こう(OSC2015 Spring/Tokyo)
MySQL 5.7が魅せる新しい運用の形
20090107 Postgre Sqlチューニング(Sql編)

More from yoku0825

PDF
逝くぞ最新版、罠の貯蔵は十分か
PDF
サーバーが完膚なきまでに死んでもMySQLのデータを失わないための表技
PDF
MySQLレプリケーションあれやこれや
PDF
MySQL 8.0で憶えておいてほしいこと
PDF
片手間MySQLチューニング戦略
PDF
MySQLを割と一人で300台管理する技術
PDF
わたしを支える技術
PDF
MySQL 5.7の次のMySQL 8.0はどんなものになるだろう
PDF
Dockerイメージで誰でも気軽にMroonga体験
PDF
MySQLアンチパターン
PDF
MySQLerの7つ道具 plus
PDF
MySQL 5.7の次のMySQLは
PDF
MySQLerの7つ道具
PDF
MHAの次を目指す mikasafabric for MySQL
PDF
5.7の次のMySQL
PDF
mikasafabric for MySQL
PDF
とあるイルカの近況報告
PDF
MySQL Fabricでぼっこぼこにされたはなし
PDF
MySQLと正規形のはなし
PDF
MySQLおじさんの逆襲
逝くぞ最新版、罠の貯蔵は十分か
サーバーが完膚なきまでに死んでもMySQLのデータを失わないための表技
MySQLレプリケーションあれやこれや
MySQL 8.0で憶えておいてほしいこと
片手間MySQLチューニング戦略
MySQLを割と一人で300台管理する技術
わたしを支える技術
MySQL 5.7の次のMySQL 8.0はどんなものになるだろう
Dockerイメージで誰でも気軽にMroonga体験
MySQLアンチパターン
MySQLerの7つ道具 plus
MySQL 5.7の次のMySQLは
MySQLerの7つ道具
MHAの次を目指す mikasafabric for MySQL
5.7の次のMySQL
mikasafabric for MySQL
とあるイルカの近況報告
MySQL Fabricでぼっこぼこにされたはなし
MySQLと正規形のはなし
MySQLおじさんの逆襲

わかった気になるMySQL


[8]ページ先頭

©2009-2025 Movatter.jp