質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
MySQL

MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

SQL

SQL(Structured Query Language)は、リレーショナルデータベース管理システム (RDBMS)のデータベース言語です。大きく分けて、データ定義言語(DDL)、データ操作言語(DML)、データ制御言語(DCL)の3つで構成されており、プログラム上でSQL文を生成して、RDBMSに命令を出し、RDBに必要なデータを格納できます。また、格納したデータを引き出すことも可能です。

データベース

データベースとは、データの集合体を指します。また、そのデータの集合体の共用を可能にするシステムの意味を含めます

Q&A

解決済

2回答

5954閲覧

MySQL 不等号AND検索のインデックス

退会済みユーザー

退会済みユーザー

総合スコア0

MySQL

MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

SQL

SQL(Structured Query Language)は、リレーショナルデータベース管理システム (RDBMS)のデータベース言語です。大きく分けて、データ定義言語(DDL)、データ操作言語(DML)、データ制御言語(DCL)の3つで構成されており、プログラム上でSQL文を生成して、RDBMSに命令を出し、RDBに必要なデータを格納できます。また、格納したデータを引き出すことも可能です。

データベース

データベースとは、データの集合体を指します。また、そのデータの集合体の共用を可能にするシステムの意味を含めます

0グッド

1クリップ

投稿2016/06/01 03:38

編集2016/06/01 03:39

下記のようなテーブルのインデックスはどう作成するのが最も速いでしょうか。
startとendの範囲からhogeを取得するのが目的で800万レコードほどです。

innodb +----------+----------+--------+ | start | end | hoge | +----------+----------+--------+ | 10000 | 11000 | test | | 11001 | 13000 | sample | | 15000 | 16000 | dummy | +----------+----------+--------+ +----------+---------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +----------+---------------+------+-----+---------+-------+ | start | decimal(10,0) | NO | | NULL | | | end | decimal(10,0) | NO | | NULL | | | hoge | varchar(128) | NO | | NULL | | +----------+---------------+------+-----+---------+-------+

sql

1SELECT * FROM sample WHERE end >= 12345 AND start <= 12345 2 3# => sample

EXPLAINを使い、いろいろ試したのですが、
だいたい以下のようなスコアでした。

インデックスなし・・・10s
startにPRIMARY・・・5s
start、end複合INDEX・・・5s
endにINDEX・・・2s

2s以上あがらないのはスペックや設定の問題でしょうか。
(innodbバッファプールなどは初期設定だったかと思います。

アドバイスいただけますでしょうか。
よろしくお願いいたします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

以下2通りを試してみてください。

endstartという順番の複合インデックス

startにPRIMARY・・・5s

endにINDEX・・・2s

という結果からendの方がカーディナリティが高いようなので、そちらを先にスキャンさせてみる。

startendそれぞれに単一カラムインデックス

インデックスマージが効くかもしれないので。
https://dev.mysql.com/doc/refman/5.6/ja/index-merge-optimization.html


インデックスの追加だけでは望むパフォーマンスが得られない場合、スペックや設定の見直しに加えてテーブルのパーティション化も検討してみてください。
https://dev.mysql.com/doc/refman/5.6/ja/partitioning.html

投稿2016/06/01 06:02

KiyoshiMotoki

総合スコア4791

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

ベストアンサー

実行に2s必要になるのは抽出行数が多いためではないでしょうか?
コストの殆どをメモリの確保やデータ構築、転送に使っているのでは?と推測します。
次のSQLなら早いのではないかと思います。

SQL

1SELECT count(*) FROM sample WHERE end >= 12345 AND start <= 12345

とか

SQL

1SELECT * FROM sample WHERE end <= 1 AND start <= 0

INDEX(ソート済み)で何が早いかというと、未ソートなら800万行1つ1つに対してend<=12345を(つまり800万回)チェックしないといけないのに対して、ソート済みなら境界値を探して、それ以下を全て取得すればいいからです。

確認処理 × 800万回 + 抽出処理 × 抽出行数 VS 確認処理 × 最大21回 + 抽出処理 × 抽出行数
※実際は未ソートでもソートしてから境界値を探すほうが早いのでそちらが実施されると思います。

INDEXが片方にしかない場合(複合INDEXでも同じ)、有るほうの抽出は早いでしょうが、無い側の速度は一つ目の条件で絞り込まれた行数に依存します。
また仮に両方に有っても、一つ目の条件で抽出されたグループに対して二つ目のINDEXは使えないか、使えても効果が薄くなると予想できます。
恐らくstartとendに個別にINDEXを作成するのが最速だと思います(オプティマイザが抽出行数が少ないほうを最初に実行するように選んでくれると思います)が、2sより劇的に早くなるかはやってみないとわかりません。

投稿2016/06/01 09:40

編集2016/06/01 09:44
hirohiro

総合スコア2068

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問