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

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

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

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

Q&A

解決済

1回答

1262閲覧

MySql:複数のテーブルの結合でインデックスが使われず速度が出ないため、修正方法を教えてほしい

yonotsui

総合スコア28

MySQL

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

0グッド

0クリップ

投稿2021/09/07 10:58

編集2021/09/07 11:06
select * from shop_ce left join (select ASIN as dhashasin,SiteImgUrlHash as dhashimage,DHashDif from dhashdiff) as dhashdiff on dhashdiff.dhashasin=shop_ce.ASIN&& dhashdiff.dhashimage=shop_ce.ImageURLHash left join (select ASIN,IsHide as UserAsinHide from userasin) as userasin using(ASIN) left join (select ASIN,URLHash,IsHide as UserShopHide from usershop) as usershop on usershop.ASIN=shop_ce.ASIN&&usershop.URLHash=shop_ce.URLHash where shop_ce.SearchBaseURL='https://kakaku.com/pricedown/';

MySqlで上記のコマンドを実行しているのですが、インデックスが使用されていないのか実行に数時間がかかります。

テーブル「shop_ce」に対して「dhashdiff」「userasin 」「usershop」を左結合し、最後にshop_ce.SearchBaseURLでwhereを行っています。
dhashdiffとの結合には列「ASIN」と「ImageURLHash」、
userasin との結合には列「ASIN」、
usershopとの結合には列「ASIN」と「URLHash」を使用しています。
shop_ceの複合インデックス「get_from_shop」はASIN、ImageURLHash、URLHash、SearchBaseURLを順番に使用しているためこちらのインデックスを使用できるはずです。
shop_ceに結合する各テーブルも、結合に使用するためのインデックスを作成しています。
文字列の列は文字コードと長さも揃えているためインデックスを使用する条件はそろっているはずです。

どうすれば高速化できるのでしょうか。
ご教示いただけますと幸いです。

explain

+----+-------------+-----------+------------+--------+-----------------------------------------------------------------+-----------------+---------+---------------------------------------------------+---------+----------+-----------------------+ | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra | +----+-------------+-----------+------------+--------+-----------------------------------------------------------------+-----------------+---------+---------------------------------------------------+---------+----------+-----------------------+ | 1 | SIMPLE | shop_ce | NULL | ref | search_base_url | search_base_url | 1026 | const | 2626040 | 100.00 | Using index condition | | 1 | SIMPLE | dhashdiff | NULL | ref | image_asin,asin,analyze_join_index,set_priority,asin_image_hash | asin_image_hash | 16 | imusedb.shop_ce.ASIN,imusedb.shop_ce.ImageURLHash | 1 | 100.00 | NULL | | 1 | SIMPLE | userasin | NULL | eq_ref | PRIMARY | PRIMARY | 12 | imusedb.shop_ce.ASIN | 1 | 100.00 | NULL | | 1 | SIMPLE | usershop | NULL | ref | PRIMARY,asin,asin_url_hash | asin_url_hash | 16 | imusedb.shop_ce.ASIN,imusedb.shop_ce.URLHash | 1 | 100.00 | NULL | +----+-------------+-----------+------------+--------+-----------------------------------------------------------------+-----------------+---------+---------------------------------------------------+---------+----------+-----------------------+

create table

shop_ce

create

1| shop_ce | CREATE TABLE `shop_ce` ( 2 `ShopName` varchar(256) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL, 3 `ShopNameOpt` varchar(256) COLLATE utf8mb4_general_ci DEFAULT NULL, 4 `SetTime` bigint(20) DEFAULT NULL, 5 `ASIN` varbinary(10) NOT NULL, 6 `SiteName` varchar(256) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL, 7 `SiteImgUrl` varbinary(2083) DEFAULT NULL, 8 `Name` varchar(256) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL, 9 `NameOpt` varchar(256) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL, 10 `URL` varbinary(2083) NOT NULL, 11 `ImageURL` varbinary(2083) DEFAULT NULL, 12 `Price` int(11) DEFAULT NULL, 13 `Postage` int(11) DEFAULT NULL, 14 `Used` bit(1) NOT NULL, 15 `DHashSetTime` bigint(20) NOT NULL, 16 `DHashDif` smallint(5) unsigned NOT NULL, 17 `IsJAN` bit(1) NOT NULL, 18 `PointRate` float(3,3) unsigned NOT NULL, 19 `SellerName` varchar(128) COLLATE utf8mb4_general_ci NOT NULL, 20 `Page` int(11) NOT NULL, 21 `SearchBaseURL` varbinary(1024) NOT NULL, 22 `URLHash` int(10) unsigned NOT NULL, 23 `ImageURLHash` int(10) unsigned NOT NULL, 24 PRIMARY KEY (`SellerName`,`ASIN`,`URL`), 25 KEY `site_shop` (`SiteName`,`ShopName`), 26 KEY `asin_name` (`ASIN`,`SellerName`), 27 KEY `asin` (`ASIN`), 28 KEY `asin_image` (`ASIN`,`ImageURL`), 29 KEY `sellerName` (`SellerName`), 30 KEY `asin_url_seller` (`ASIN`,`URL`,`SellerName`), 31 KEY `search_base_url` (`SearchBaseURL`), 32 KEY `asin_image_site` (`ASIN`,`ImageURL`,`SiteName`), 33 KEY `asin_search_base_url` (`ASIN`,`SearchBaseURL`), 34 KEY `get_from_seller` (`ASIN`,`ImageURLHash`,`URLHash`,`SellerName`), 35 KEY `get_from_shop` (`ASIN`,`ImageURLHash`,`URLHash`,`SearchBaseURL`) 36) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci |

dhashdiff

| dhashdiff | CREATE TABLE `dhashdiff` ( `SiteImgUrl` varbinary(2083) NOT NULL, `DHashDif` smallint(5) unsigned NOT NULL, `SetTime` bigint(19) unsigned NOT NULL, `ASIN` varbinary(10) NOT NULL, `SiteName` varchar(64) COLLATE utf8mb4_general_ci NOT NULL, `UrlAndASINHash` int(10) unsigned NOT NULL, `SiteImgUrlHash` int(10) unsigned NOT NULL, PRIMARY KEY (`SiteImgUrl`,`ASIN`,`SiteName`), KEY `image_asin` (`ASIN`,`SiteImgUrl`), KEY `settime_index` (`SetTime`), KEY `asin` (`ASIN`), KEY `analyze_join_index` (`ASIN`,`SiteImgUrl`,`SiteName`,`SetTime`), KEY `set_priority` (`ASIN`,`SiteImgUrl`,`SiteName`,`DHashDif`), KEY `asin_url_hash` (`UrlAndASINHash`), KEY `asin_image_hash` (`ASIN`,`SiteImgUrlHash`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci |

userasin

| userasin | CREATE TABLE `userasin` ( `ASIN` varbinary(10) NOT NULL, `IsHide` bit(1) NOT NULL, `HideTime` bigint(20) NOT NULL, `HideTimeSetTime` bigint(20) NOT NULL, `UserSettingTime` bigint(20) NOT NULL, `Comment` varchar(252) COLLATE utf8mb4_general_ci NOT NULL, PRIMARY KEY (`ASIN`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci |

usershop

| usershop | CREATE TABLE `usershop` ( `ASIN` varbinary(10) NOT NULL, `IsHide` bit(1) NOT NULL, `HideTime` bigint(20) NOT NULL, `HideTimeSetTime` bigint(20) NOT NULL, `UserSettingTime` bigint(20) NOT NULL, `Comment` varchar(252) COLLATE utf8mb4_general_ci NOT NULL, `URL` varbinary(2083) NOT NULL, `URLHash` int(10) unsigned NOT NULL, PRIMARY KEY (`ASIN`,`URL`), KEY `asin` (`ASIN`), KEY `asin_url_hash` (`ASIN`,`URLHash`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci |

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

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

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

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

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

yambejp

2021/09/08 00:54 編集

left joinが必須の仕組みなのでしょうか? left joinではパフォーマンスはあまり期待できないですが・・・ left join後にwhereするのも効率的ではないかもしれません (where句での絞り込みがリレーションに絡まないみたいですし)
FKM

2021/09/08 05:07 編集

結合、まして不完全結合の場合、select対象のカラム指定にアスタリスクはやめた方がいいですよ。テーブル名.カラム名を逐一明示しないと結合している全部のテーブルを場当たりで調べることになってしまいます。
yonotsui

2021/09/09 18:44

>left joinが必須の仕組みなのでしょうか? left joinせず個別に取得する手も考えましたが、取得するshop_ceの行数が膨大なため断念しました。 現状はleft joinなどの外部結合でしか実装できないものと考えています。 >left join後にwhereするのも効率的ではないかもしれません おっしゃる通りwhereを先にしたほうが効率的でした。 順序を変えることで改善できました。 >結合、まして不完全結合の場合、select対象のカラム指定にアスタリスクはやめた方がいいですよ。テーブル名.カラム名を逐一明示しないと結合している全部のテーブルを場当たりで調べることになってしまいます。 ワイルドカードは負荷がかかるのですね。 恥ずかしながら全く把握しておりませんでした。 列名を直接指定するように修正させていただきました。 おかげさまで問題を改善することができました。 お二人ともアドバイス頂きありがとうございました。
guest

回答1

0

自己解決

下記のコマンドに修正しました。

with shop_ce as (select * from shop_ce where shop_ce.SearchBaseURL='https://kakaku.com/pricedown/') select shop_ce.ShopName,shop_ce.SellerName,shop_ce.ShopNameOpt,shop_ce.SetTime,shop_ce.Page,shop_ce.SearchBaseURL,shop_ce.URLHash,shop_ce.ImageURLHash,shop_ce.ASIN,shop_ce.SiteName,shop_ce.SiteImgUrl,shop_ce.Name,shop_ce.NameOpt,shop_ce.URL,shop_ce.ImageURL,shop_ce.Price,shop_ce.Postage,shop_ce.Used,shop_ce.DHashSetTime,shop_ce.DHashDif,shop_ce.IsJAN,shop_ce.PointRate, userasin.IsHide as UserAsinHide, usershop.IsHide as UserShopHide, dhashdiff.DHashDif as DHashDifWork from shop_ce left join dhashdiff on dhashdiff.ASIN=shop_ce.ASIN&& dhashdiff.SiteImgUrlHash=shop_ce.ImageURLHash left join userasin on shop_ce.ASIN=userasin.ASIN left join usershop on usershop.ASIN=shop_ce.ASIN&& usershop.URLHash=shop_ce.URLHash;

shop_ceのSearchBaseURLを定数でwhereしてから左結合するように修正しました。
そのためにshop_ceの複合インデックスをSearchBaseURL,ASIN,ImageURLHash,URLHashの順に変更しました。
SELECT文の評価順序に従ってインデックスを作成するよりこちらの方が早いためです。
現状処理時間は1秒前後に納まりました。
高速化は不十分だと思いますが許容範囲ではあるので、この状態で運用します。
みなさまアドバイス頂きありがとうございました。

投稿2021/09/09 18:35

yonotsui

総合スコア28

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.46%

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

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

質問する

関連した質問