MySQLのテーブル連結でクエリに4分以上かかる

このQ&Aのポイント
  • MySQLのテーブル連結を行うクエリが4分以上かかる現象が発生しています。テーブル内のレコード数に対してクエリの実行時間が非常に長いため、処理時間を短縮したいと考えています。
  • クエリの実行にはPHPやCLIのmysqlを使用しており、いずれの環境でも同様の結果となります。テーブル内のレコード数はarticlesが738,338件、titlesが34,821件です。
  • ハードウェアの性能限界やテーブルの連結方法による影響など、クエリの処理時間を短縮するためのヒントを求めています。
回答を見る
  • ベストアンサー

MySQLのテーブル連結でクエリに4分以上かかる

初めまして、よろしくお願いします。 現在PHPよりアクセスするクエリを作成しています。 mysql> select distinct titles.culumn1, title from articles, titles where user = 'userid' and articles.culumn1 = titles.culumn1 and datetime like '2007-11-18%'; Empty set (4 min 42.79 sec) 上記のようなSQL文を作ってPHPからとCLIのmysqlから実行してみたところ、どちらも結果が出るまでに4分以上かかってしまいます。 テーブル内のレコード数としては以下のようになっています。 mysql> select count(*) from articles; +----------+ | count(*) | +----------+ | 738338 | +----------+ 1 row in set (0.00 sec) mysql> select count(*) from titles; +----------+ | count(*) | +----------+ | 34821 | +----------+ 1 row in set (0.00 sec) できればこのクエリの時間を4分から3秒程度にまで短縮したいと考えています。 これは、やはりハードウェアの性能限界なのでしょうか? またはテーブルの連結をせずに一つのテーブルにまとめてしまった方がいいのでしょうか? どなたかヒントでも頂ければ幸いです。 ぜひ、よろしくお願い致します。

  • MySQL
  • 回答数1
  • ありがとう数2

質問者が選んだベストアンサー

  • ベストアンサー
  • yambejp
  • ベストアンサー率51% (3827/7415)
回答No.1

EXPLAINで構文チェックしてみてください。 おそらくインデックスが働いていないのでしょう。 (1)articlesテーブルとtitlesテーブルのculumn1、 title、datetimeにそれぞれインデックスを設定する。 (プライマリならそれでもよい) (2)datetimeにlikeではインデックスはきいてません。 `datetime` BETWEEN '2007-11-18' AND '2007-11-19' としてください。

satsukima
質問者

お礼

早速のご回答ありがとうございます。 articlesテーブルとtitlesテーブルのculumn1に部分インデックスを追加して同じクエリを実行したところ、1秒強で結果が返ってくるようになりました!^^ 他のアドバイスについても今後、必要に応じて使っていきたいと思います。 的確なアドバイスを、本当にありがとうございました。非常に助かりました。

関連するQ&A

  • MySQL 5.1 のCHAR(M)型に関して

    MySQL 5.1の CHAR(M)型のMは「文字数」でしょうか?それとも「バイト数」でしょうか? 教えて頂けませんか? 自分の認識では「文字数」と思っているのですが、下記のような現象が発生しております。 mysql> mysql> mysql> mysql> mysql> SHOW CREATE TABLE TEST\G; *************************** 1. row *************************** Table: TEST Create Table: CREATE TABLE `TEST` ( `MOJI` char(6) DEFAULT NULL ) ENGINE=InnoDB DEFAULT CHARSET=utf8 1 row in set (0.01 sec) ERROR: No query specified mysql> mysql> SELECT * FROM TEST; Empty set (0.00 sec) mysql> mysql> INSERT INTO TEST (MOJI) VALUES ('ああああ'); Query OK, 1 row affected, 1 warning (0.00 sec) mysql> mysql> SELECT * FROM TEST; +--------+ | MOJI | +--------+ | ああ | +--------+ 1 row in set (0.00 sec) mysql> mysql> INSERT INTO TEST (MOJI) VALUES ('abcdef'); Query OK, 1 row affected (0.00 sec) mysql> mysql> SELECT * FROM TEST; +--------+ | MOJI | +--------+ | ああ | | abcdef | +--------+ 2 rows in set (0.00 sec) mysql> mysql> mysql> mysql> 環境はCentOS 5.5 で、OSの文字コードもMySQLの文字コードも「utf8」としています。 どうかご教授下さい。

  • MySQL + PHP 同じテーブル内でのクエリについて

    PHP+MySQL勉強中の初心者です。 PHP+MySQL環境でのクエリについて、以下の条件でのクエリ結果を求めたいのですが、上手くできませんので、質問させてください。 MySQLのテーブルは以下のようになっています。 date        no   name ---------------------------- 2009-12-10   15   takada 2009-12-15   10   hirooka 2009-12-18   13   wakada 2010-01-10   15   takada 2010-01-11   13   wakada ----------------------------- 出力させたいクエリは、前月データを元にno列をKEYとした重複チェックです。 前月データを全件出力し、当月データに同じnoがあった場合、当月日付を 表示させたいと思っています。 (PHPで希望する出力結果) date       no   name     date2 ---------------------------------------- 2009-12-10  15   takada   2010-01-10 2009-12-15  10   hirooka 2009-12-18  13   wakada   2010-01-11 ----------------------------------------- 以下のようなソースでは、1行のみの出力結果しか表示されず、 whileの使い方に問題があると思うのですが、どのように解決すれば良いのかが解りません。 どうか、解決策をよろしくお願いいたします。 $mysql->query("SELECT * FROM xxxx where date LIKE '$y-$m%'"); while($row = $mysql->fetch()){ $date = $row["date"]; $no = $row["no"]; $name = $row["name"]; $mysql->query("SELECT * FROM xxxx where upddate LIKE '$y2-$m2%' and no = '$no'"); while($row = $mysql->fetch()){ $date2 = $row["date"]; echo <<<EOT <td>$date</td> <td>$no</td> <td>$name</td> <td>$date2</td><tr> EOT; } }

    • 締切済み
    • PHP
  • mysqlについてサンプルなど教えてもらえませんか

    すいません。今phpなどを使いウェブサイトを作っているのですが、データベースがどうしても 必要となり、参考サイトなどを見ながら作りました。 ほとんどできたのですが、最後に一部データベースの関数などでわからない事があり困っています。 (正直私はプログラムはphp程度が少し分かる程度で、データベースも単純な使い方しかしない 予定なので参考サイトをざっと見ただけでmysqlの事がほとんど分かりません) ググってそれらしい物を探してはいるのですが、私がやりたい事はデータベースから 件数を取りたいだけです。 取った件数をphpで表示したいのですが、何時間やっても良くわかりません。 申し訳ないんですが取り出した後その件数をphpのechoで表示するまでをサンプルとして書いてもらえませんか?(可能であれば「ここでこのような処理が行われている」とコメントがもらえると助かります) データベース関係はphpと違って初心者用のサイトなども無く、書いてある事がほとんど分かりません。 (ここでSELECT COUNT(*)を使うと教えてもらったのですが、SELECT COUNT(*)でググっても サンプルなども出てきません) $pdo = new PDO("mysql:dbname=aaa", "root"); $pdo->query("set names utf8;"); // ------------------------------------------------ $sql = $pdo->query("SELECT COUNT(*) FROM bbb"); $stmt = $pdo->query($sql); $stmt->execute(); $count=$stmt->rowCount(); echo $count; ----------------------------------------------- $result = mysql_query("SELECT COUNT(*) FROM bbb"); $row = mysql_fetch_assoc( $result ); echo $row;

    • ベストアンサー
    • MySQL
  • Mysql ストアドファンクション 意図しない結果

    以下の通りストアドファンクションを作成しました。 関数名:fgetLineNew インパラメータ:shop Varchar 8 ※1つだけ。。。 戻り値: Int 11 <ソース> BEGIN DECLARE pline INTEGER(11) DEFAULT NULL; SELECT COUNT(1) INTO pline FROM `hoge` WHERE `SHOP` = shop; IF pline IS NULL THEN SET pline = 10000; END IF; RETURN pline; END 上記のように、作成したストアドファンクションですが、 どんな引数を入れても、戻り値が全ての行(817行)になってしまいます。 以下を参照。 Where区がまったく働いていないのですが、何が原因なのでしょうか。 教えてください。 <ストアドファンクション実行> mysql> select fgetLineNew(1); +----------------+ | fgetLineNew(1) | +----------------+ | 817 | +----------------+ 1 row in set (0.01 sec) mysql> select fgetLineNew(525); +------------------+ | fgetLineNew(525) | +------------------+ | 817 | +------------------+ 1 row in set (0.01 sec) mysql> select fgetLineNew(101); +------------------+ | fgetLineNew(101) | +------------------+ | 817 | +------------------+ 1 row in set (0.00 sec) mysql> select fgetLineNew(525); +------------------+ | fgetLineNew(525) | +------------------+ | 817 | +------------------+ 1 row in set (0.00 sec) mysql> select fgetLineNew('525'); +--------------------+ | fgetLineNew('525') | +--------------------+ | 817 | +--------------------+ 1 row in set (0.01 sec)

    • ベストアンサー
    • MySQL
  • MAX_ROWSが反映されていない?

    Mysql5.0.22-standardで65535行では足りないため増やそうとしています。 一応 truncate table test5; とした後に ALTER TABLE test5 MAX_ROWS=1000000000 AVG_ROW_LENGTH=10000;で Query OK, 0 rows affected (0.01 sec) Records: 0 Duplicates: 0 Warnings: 0 と出るのですが、 PHPで検査のためにデータを登録させていくと65535行でエラーが出て、 SELECT COUNT(*) FROM test5; +----------+ | COUNT(*) | +----------+ | 65535 | +----------+ 1 row in set (0.00 sec) の状態です。 反映するために何かコマンド必要なのでしょうか?

  • PHP / MySQL / クエリ実行

    【概要】 PHPからMySQLへのクエリを実行したいのですが、結果が返りません。 【環境】 CentOS5 [PHP5] sakuraインターネット レンタルサーバ スタンダートプランです。 参考:http://www.sakura.ne.jp/rentalserver/matrix.html 【ソース PHP】 ------------------------------------------------------------ $query =  mysql_query(' SET @i := 0; SET @ii := 0; SET @iii := 0; SET @iiii := 0; select `sys_no`,`day`,`counter`,(@iiii := @iiii +1)as `counter2` from (select `sys_no`,`name`,`day`,(@i := @i +1) as `counter` from TBL名 ORDER BY `day` DESC ) as aa where counter BETWEEN (select a.counter from (select `sys_no`,`day`,(@ii := @ii +1) as `counter` from TBL名 ORDER BY day DESC ) as a where sys_no =5) - 1 AND (select a.counter from (select `sys_no`,`day`,(@iii := @iii +1) as `counter` from TBL名 ORDER BY day DESC ) as a where sys_no =5) + 1 '); while ($row = mysql_fetch_array($query)) { 結果取得処理 } ------------------------------------------------------------ ・上記をPHPより実行しますと、「while~」の部分で結果が無いとエラーが返ります。 ・phpMyAdminから直接クエリの部分のみを実行しますと、問題無く結果が返ります。 ・なお、クエリを簡単な一行程度の内容にしますと問題無く実行され、結果が返ります。例:select * from TBL名 ・また、上部にセットしている4つのSETを試しに削除した状態でPHPより実行しますと、結果は返りませんがエラーにはなりません。 以上、アドバイス頂戴できますでしょうか。 よろしくお願い致します。

    • ベストアンサー
    • PHP
  • phpMyadminとPHP上からの違い?

    おせわになります よろしくお願いします SELECT COUNT(*) FROM テーブル名 WHERE dee = 0 AND Fee LIKE '%文字%' というSQL文があり、 phpMyadmin上からSQLを実行すると 4と表示されるのですが PHPから $sql = "SELECT COUNT(*) FROM テーブル名 WHERE dee = 0 AND Fee LIKE '%文字%'"; $result = mysql_query($sql,$conn); $row = mysql_fetch_row($result); とすると0、$row[0]は0となります 特にエラーの表示もなく データベースへの接続も問題ないようなのですが 原因がわかるかたいらっしゃいましたら 教えて下さい 以上よろしくお願いします

    • ベストアンサー
    • PHP
  • MySQLが動かない(テーブルレコード全表示したい

    初心者です。 いろいろ検索して改善していったつもりですが、なぜ動かないのかどうしてもわからないところがあったので質問させていただいてます。 /* サーバーへの接続 */ $link=mysql_connect($server,$user,$passwd); /* データベース内のテーブルの名前を$tablesに配列で格納 */ $STS = "SHOW TABLE STATUS"; $mytables = mysql_query($STS); while($r = mysql_fetch_array($mytables, MYSQL_ASSOC)){ $tables[] = ($r["Name"]."<br>\n"); } /* 全テーブルのレコードを全てプリント */ foreach($tables as $value){ $results = mysql_query("select * from " . $value, $link); while ($row = mysql_fetch_array($results, MYSQL_ASSOC)) { print_r($row); print("<br>\n"); } } mysql_close($link); foreachの部分を for($i = 0; $i < 2 /*$tables[$i] != 0*/; $i++){ $results = mysql_query("select * from " . $tables[$i], $link); $row = mysql_fetch_array($results, MYSQL_ASSOC); print_r($row); } でもやってみました。 これを利用して、何とか表形式でデータベースのテーブルのレコードをwebページに出力させようと思っています。 実行するとprint_r($row)の出力がでず、いろいろ試してみた結果、$resultsもしくは$rowに問題があることがわかりました。 var_dump($row); でNULLが出力されました。 var_dump($results); もやったのですが、うろ覚えなのでここには書きません。 $results = mysql_query("select * from gutaiteki_table", $link); としたら動いたので、select * from の後に変数を続けているからだめなのかなと思いましたが、私にはどうにもしようがありません。 これを正常に動作させる方法、他にうまいやり方があればその方法を教えてほしいです。 (私はデバッグのやり方がわからないので、「改変してwebのページを更新する」というのを繰り返してプログラムを作成していますが、他に方法があればそれも併せてご意見ほしいです。これは余裕があったらで構いません。)

  • どちらが速いのか?mysql_num_rows

    どちらの処理が早くなりますか?またメモリの使用量はどちらが優れているのでしょうか? また、方法Bのクエリ実行は2回だと思いますが、方法Aはクエリの実行は一回と考えてもいいのでしょうか? PHPとMySQLの環境です。 また、評価のやり方も教えて頂ければ大変ありがたいです。 ■方法A $q = "SELECT key, a, b, c FROM d WHERE a < 1 AND b > 1 ORDER BY c"; $rs = mysql_query ($q); $row_num = mysql_num_rows ($rs); while ($data = mysql_fetch_array ($rs)) { echo $data[key] . $data[a] . $data[b] . $data[c]; } ■方法B $q_c = "SELECT COUNT(key) AS count FROM d WHERE a < 1 AND b > 1"; $rs = mysql_query ($q_c); $data = mysql_fetch_array ($rs); $row_num = $data[count]; $q = "SELECT key, a, b, c FROM d WHERE a < 1 AND b > 1 ORDER BY c"; $rs = mysql_query ($q); while ($data = mysql_fetch_array ($rs)) { echo $data[a] . $data[b] . $data[c]; } 是非宜しくお願い致します。

    • ベストアンサー
    • PHP
  • mysql_fetch_assoc()の非推奨

    phpを始めてまだ数ヶ月の初心者です。 (少々表現が変なところはお許し下さい。) ■やりたい事 phpである登録画面を作成しています。サーバーには スタッフのデーターが入っているテーブルがあります。 (1)DBに登録してあるスタッフの名前を全部引っ張り出す(mysql)。 (2)登録画面の入力項目の1つとして(登録スタッフ)があり、  そこを<select>で上記(1)から取り出したものを自動で表示したい。 ところが、mysql_fetch_assoc()について調べたら、非推奨などと載っていて (内容がよく理解できませんでしたが)どのように記述したら、将来困らない  コーディングとなりますか? <select name="register"> <?php $sql = "select count_ID, name from reserve"; $result = mysql_query($sql); while ($row = mysql_fetch_assoc($result)) { echo "<option value=\"".$row["count_ID"]."\">" .$row["name"]."</option>"; } ?> </select> 今からphpの知識を少しづつつけていくにあたり、非常に混乱して います。mysqlをそもそも学んでいてもしょうがないということでは ないですよね。本当に初心者なので、お手数ですがわかりやすい表現 でお願いします。 よろしくお願いします。

    • ベストアンサー
    • PHP