ユーザーが自由形式のテキストボックスで検索を実行した後、(eコマースサイトで)製品を返すために使用されるMySQLデータベースにクエリがあります。
最近まで、ユーザー検索は高速で実行されていました。ただし、過去数日間、検索は定期的に非常に遅くなります。これは、毎日約3〜4時間(1日を通してランダムに広がる)発生します。
サーバーに問題があると思っていました。しかし今、私は別のサーバーに移動しました、そして同じことがまだ起こります。
私が使用しているクエリは非常に非効率的であると思われます。おそらくこれが原因です。しかし、なぜ通常はクエリが高速に実行され、他の場合には非常に低速になるのか理解できません。非効率的なクエリは常に遅いと思います。
クエリは2つのテーブルで実行されます。「ブルージーンズ」を検索すると、クエリは次のようになります。
SELECT I.itemURL, I.itemTitle, I.itemPrice, I.itemReduced, I.itemFileName, I.itemBrand, I.itemStore, I.itemID, I.itemColour, I.itemSizes, I.itemBrandEn
FROM Item AS I, Search AS S
WHERE I.itemID = S.itemID
AND (S.searchStringTEXT LIKE '% blue %' OR S.searchStringTEXT LIKE 'blue %' OR S.searchStringTEXT LIKE '% blue')
AND (S.searchStringTEXT LIKE '% jeans %' OR S.searchStringTEXT LIKE 'jeans %' OR S.searchStringTEXT LIKE '% jeans')
アイテムは、サイト上のすべての製品を含むテーブルです。約100,000行あります。
検索は、製品IDと、各製品IDに関連付けられたタグを含むテーブルです。タグは「searchStringTEXT」列にあり、スペースで区切られています。たとえば、この列のエントリは「ジーンズブルーカルバンクラインスモール」のようなものです。
上記の検索では、「ジーンズ」と「青」の両方のタグが付いているすべてのアイテムが見つかります。
理論的には、検索にはアイテムと同じ行数が必要です。ただし、まだ修正していない問題のため、行数が約500少ないため、これらの項目は事実上検索から除外されます。
両方のテーブルのテーブル作成の詳細は次のとおりです。
CREATE TABLE `Search` (
`itemID` int(11) NOT NULL,
`searchStringTEXT` varchar(255) DEFAULT NULL,
`searchStringVARCHAR` varchar(1000) DEFAULT NULL,
PRIMARY KEY (`itemID`),
KEY `indexSearch_837` (`itemID`) USING BTREE,
KEY `indexSearch_837_text` (`searchStringTEXT`)
) ENGINE=InnoDB DEFAULT CHARSET=latin5
と
CREATE TABLE `Item_8372` (
`itemID` int(11) NOT NULL AUTO_INCREMENT,
`itemURL` varchar(2000) DEFAULT NULL,
`itemTitle` varchar(500) DEFAULT NULL,
`itemFileName` varchar(200) DEFAULT NULL,
`itemPictureURL` varchar(2000) DEFAULT NULL,
`itemReduced` int(11) DEFAULT NULL,
`itemPrice` int(11) DEFAULT NULL,
`itemStore` varchar(500) DEFAULT NULL,
`itemBrand` varchar(500) CHARACTER SET latin1 DEFAULT NULL,
`itemShopCat` varchar(500) DEFAULT NULL,
`itemTimestamp` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
`itemCat` varchar(200) DEFAULT NULL,
`itemSubCat` varchar(200) DEFAULT NULL,
`itemSubSubCat` varchar(200) DEFAULT NULL,
`itemSubSubSubCat` varchar(200) DEFAULT NULL,
`itemColour` varchar(200) DEFAULT NULL,
`itemSizes` varchar(200) DEFAULT NULL,
`itemBrandEn` varchar(500) DEFAULT NULL,
`itemReduction` float DEFAULT NULL,
`ItemPopularity` int(6) DEFAULT NULL,
PRIMARY KEY (`itemID`),
KEY `indexItem_8372_ts` (`itemTimestamp`) USING BTREE,
KEY `indexItem_8372_pop` (`ItemPopularity`),
KEY `indexItem_8372_red` (`itemReduction`),
KEY `indexItem_8372_price` (`itemReduced`)
) ENGINE=InnoDB AUTO_INCREMENT=970846 DEFAULT CHARSET=latin5
質問のタイトルで「(私のWebサイトで実行した場合)」と言います。これは、ローカルで実行した場合にクエリの速度が一定であることがわかったためです。しかし、これは私がローカルであまりテストしていないからかもしれません。
SearchテーブルをMyISAMテーブルに変更することを考えています。そうすれば、「LIKE」の代わりに全文検索を使用できます。しかし、私はまだ、現在のセットアップで経験していることをなぜ経験しているのかを理解したいと思います。
アンドリュー、どんなアイデア/提案も大歓迎です
編集:
SELECTステートメントのEXPLAIN結果は次のとおりです。
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE I ALL PRIMARY NULL NULL NULL 81558
1 SIMPLE S eq_ref PRIMARY,indexSearch_837,indexSearch_837_text PRIMARY 4 I.itemID 1 Using where