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

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

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

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

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

Q&A

解決済

2回答

220閲覧

Mysql の SELECT 表記について

alkeran

総合スコア29

MySQL

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

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

0グッド

0クリップ

投稿2019/12/04 13:18

編集2019/12/05 00:30

以下のコードですが、xxxテーブルからデータを抽出して表示したいのですが、⇒矢印の行を追加すると表示時間が異常に遅くなり、抽出データの量によっては timeout することがあります。表示時間を短くしtimeoutを避けるためにはどうしたらよろしいでしょうか?ご教授お願い致します。

<追記>
create table xxx (id int, AAA varchar(100), BBB varchar(100),CCC varchar(100),DDDvarchar(20));
AAA   BBB    CCC    DDD
====================
チョコ  170円 菓子類   111A
チョコ  160円 菓子類 111A
アイス  200円 アイス類 111B

ざっくりいうと、DDDの値が同一なら、AAAの値を重複させずに表示させたいのです。
(表示結果が「チョコ、チョコ、アイス」ではなく「チョコ、アイス」にしたい)

php

1<?php 2 3 $pdo = new PDO("mysql:host=xxx; dbname=db; charset=utf8", "xxx", "pass", array( PDO::ATTR_EMULATE_PREPARES => false ) ); 4 $sql = "select * from xxx where 1 = 1 "; 5 $condition = array(); 6 7 if( !empty( $_REQUEST["drug"] ) ){ 8 $sql = $sql . " and ( AAA like :aaa or BBB like :bbb or CCC like :ccc ) ";  9  ⇒$sql = $sql . " and ( id IN(SELECT min(id) FROM xxx GROUP BY DDD) ) "; 10 11 $condition[":aaa"] = "%{$_REQUEST["aaa"]}%"; 12 $condition[":bbb"] = "%{$_REQUEST["bbb"]}%"; 13 $condition[":ccc"] = "%{$_REQUEST["ccc"]}%"; 14 15 } 16 17 $statement = $pdo->prepare( $sql ); 18 $statement->execute( $condition ); 19 $results = $statement->fetchAll(); 20 21foreach ($results as $result) { 22 23print $result['AAA']; 24} 25?> 26

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

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

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

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

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

m.ts10806

2019/12/04 14:10

テーブル定義とサンプルデータをSQLでご提示ください
alkeran

2019/12/04 14:29

create table xxx (id int, AAA varchar(100), BBB varchar(100),CCC varchar(100),DDDvarchar(20)); AAA   BBB    CCC    DDD ==================== チョコ  170円 菓子類   111A チョコ  160円 菓子類 111A アイス  200円 アイス類 111B
alkeran

2019/12/04 14:32

ざっくりいうと、DDDの値が同一なら、AAAの値を重複させずに表示させたいのです。 (表示結果が「チョコ、チョコ」ではなく「チョコ」のみ)
m.ts10806

2019/12/04 21:23

質問は編集できますので編集願います。
alkeran

2019/12/05 00:26

承知しました。ありがとうございます。
XNXSXMXR

2019/12/05 00:46

「⇒」のクエリで最小の id を求めていますが、この条件を入れると「160円」のデータはヒットしなくなりませんか?
alkeran

2019/12/05 01:14

初心者のため的を得ていない返答なら申し訳ありません。160円のチョコは表示させたくありません。DDDのカラムでお菓子のコードが一緒ならAAAカラムの表記は1種類にしたいのです。ただ、今回は表示はできるのですが、それまでの時間がものすごくかかってしまいます。
XNXSXMXR

2019/12/05 01:18

なるほど、表示されなくても良いのが織り込み済みということですね。
guest

回答2

0

ベストアンサー

他の回答者様にもご指摘があるように、どこでどのように遅くなっているか「実行計画」(explain)を行ってみる必要があるかと思います。

SQLを直接実行できる環境(コンソールだったりphpMyAdminだったり他ツールでも)はありますか?

SQL

1explain analyse 2select * from xxx where 1 = 1 3 and ( AAA like '%チ%' or BBB like '%円%' or CCC like '%類%' ) 4 and (id in (select min(id) from xxx group by DDD));

※上記「%チ%」や「%円%」は適当に指定しています。
実際にブラウザで入力している値を「%」と「%」の間にセットしてみてください。

これを実行し、結果を質問欄に追記してください。
何か原因が見つかるかもしれません。

思ったのが、LIKE検索は全件検索しに行くので、データ件数が多いほど時間がかかります。

投稿2019/12/05 01:36

XNXSXMXR

総合スコア239

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

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

alkeran

2019/12/05 15:16

以下のエラーコードが表示されました。id数は62913個あります。やはりid数が多いため時間がかかるのでしょうか?like検索が重くしていると思い、⇒の行を外して実行したが素早く表示されました。もしかして、group by DDD が原因でしょうか? #1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'select * from xxx where 1 = 1 and ( AAA like '~
XNXSXMXR

2019/12/06 00:16 編集

実際に実行したSQLをご提示ください。
alkeran

2019/12/06 13:15

以下のコードです。 explain analyse select * from xxx where 1 = 1 and ( AAA like '%チ%' ) and (id in (select min(id) from xxx group by DDD));
XNXSXMXR

2019/12/07 12:10

1つスペルミスがありました。 「explain analyse」ではなく、「explain analyze」でした。すみません。 あと、こちらで同様のテーブルと8万件のレコードを作って試してみましたが、1~2秒で結果が取得できました。 質問者さまの環境と異なるので単純な比較ができないのですが、実行計画のクエリ(スペルを直して)をもう一度実行してみてください。 ●マシンスペック(仮想マシン) ・CPU ... i5 2.5GHz (1コア) ・メモリ ... 1024MB ・MySQL ... Ver.8.0.18 ■実行結果 mysql> explain analyze -> select * from xxx2 where 1 = 1 -> and ( AAA like '%チ%' ) -> and (id in (select min(id) from xxx2 group by DDD)); +---------------------------------------------------------------------------+ | EXPLAIN | +---------------------------------------------------------------------------+ | -> Filter: ((xxx2.AAA like '%チ%') and <in_optimizer>(xxx2.id,xxx2.id in (select #2))) (cost=8069.75 rows=8867) (actual time=844.340..1566.456 rows=6 loops=1) -> Table scan on xxx2 (cost=8069.75 rows=79815) (actual time=0.030..402.315 rows=81798 loops=1) -> Select #2 (subquery in condition; run only once) -> Table scan on <temporary> (actual time=0.005..0.026 rows=10 loops=1) -> Aggregate using temporary table (actual time=844.145..844.202 rows=10 loops=1) -> Table scan on xxx2 (cost=8069.75 rows=79815) (actual time=0.011..373.403 rows=81798 loops=1) | +---------------------------------------------------------------------------+ 1 row in set (1.57 sec)
alkeran

2019/12/26 07:13

返信が遅れまして、申し訳ございませんでした。 SELECT DISTINCT により、時間がかからず表示することができました。 解決方法を提案していただいたXNXSXMXRさんをベストアンサーにしたいと思います。 他の皆様もありがとうございました。
guest

0

質問に CREATE TABLE, CREATE INDEX を追記してください。
MySQL SQL実行計画の疑問解決には「とりあえずEXPLAIN」しよう も質問に追記できた方が良いです。

 ⇒$sql = $sql . " and ( id IN(SELECT min(id) FROM xxx GROUP BY DDD) ) ";

DDD列とid列でインデックスが設定されていなければインデックスを追加してみては?

投稿2019/12/04 13:31

Orlofsky

総合スコア16415

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

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

alkeran

2019/12/04 13:48

create table xxx (id int, AAA varchar(100), BBB varchar(100),CCC varchar(100),DDDvarchar(20)); 申し訳ございません。ご指摘ありがとうございます。id列にindexが追加されています。DDD カラムは計12桁の英数字(アルファベットが1文字のみ)の文字列です。
Orlofsky

2019/12/04 13:53

質問に追記してください。 DDDとidの2つの列でインデックスを追加してください。
Orlofsky

2019/12/04 13:55

インデックスの追加の前と後での実行計画の追記も忘れずに。
alkeran

2019/12/04 13:57

DDDとidの2つの列にindexを追加しました。
alkeran

2019/12/04 14:00

"Internal Server Error"というエラーが出ました。
alkeran

2019/12/04 14:19

ありがとうございます。
m.ts10806

2019/12/05 00:30

そこで納得しちゃうのか…
Orlofsky

2019/12/05 00:40

有償サイトや対面のセミナーで勉強した方がよろしいかと。
Orlofsky

2019/12/05 00:46

各列もなるべくわかり易いネーミングに書き直したほうが良いんですけどね。 昔、NECが作ったかアドバイスしたCOBOLで項目名が連番で統一されているシステムが酷すぎて、システム部の部長の了解を取って全部作り直したことがあります。項目名のミスが原因のバグがボロボロ見つかりました。全面的に作り直して、同じハードウェア・同じデータ量で15時間かかっていたバッチが1時間で終わりました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問