0

私はMySQLの初心者です。次の構造のテーブルがあります。

CREATE TABLE `gc_ads` (
  `n` int(10) unsigned NOT NULL DEFAULT '0',
  `title` varchar(255) NOT NULL DEFAULT '',
  `detail` text NOT NULL,
  `c` char(6) DEFAULT NULL,
  `c_path` char(24) DEFAULT NULL,
  `a` char(8) DEFAULT NULL,
  `a_path` char(32) DEFAULT NULL,
  `created` int(10) unsigned NOT NULL DEFAULT '0',
  `edited` int(10) unsigned NOT NULL DEFAULT '0',
  `t1` int(10) unsigned NOT NULL DEFAULT '0',
  `t2` int(10) unsigned NOT NULL DEFAULT '0',
  `status` set('waiting','enabled','disabled','queue','wait','preview') NOT NULL DEFAULT '',
  `en_cats` tinyint(1) NOT NULL DEFAULT '0',
  `home_page` int(10) unsigned NOT NULL DEFAULT '0',
  PRIMARY KEY (`n`,`t1`,`t2`,`status`,`en_cats`),
  KEY `home_page_featured` (`status`,`home_page`),
  KEY `recount_index` (`c_path`,`a_path`,`t1`,`t2`,`status`),
) ENGINE=InnoDB DEFAULT CHARSET=utf8

次のクエリを実行する必要があります。

select * from gc_ads where c_path in ("_9_","_9_30_","_9_101_","_9_102_","_9_103_","_9_105_","_9_106_","_9_30_132_","_9_30_133_","_9_30_134_","_9_30_135_","_9_30_136_","_9_30_137_","_9_30_138_","_9_30_139_","_9_30_140_","_9_30_141_","_9_30_142_","_9_30_143_","_9_30_144_","_9_30_145_","_9_30_146_","_9_30_147_","_9_30_148_","_9_30_149_","_9_30_150_","_9_30_151_","_9_30_152_","_9_30_153_","_9_30_154_","_9_30_155_","_9_30_156_","_9_30_157_","_9_30_158_","_9_30_159_","_9_30_160_","_9_30_161_","_9_30_162_","_9_101_222_","_9_101_221_","_9_101_220_","_9_101_219_","_9_101_218_","_9_101_217_","_9_101_216_","_9_101_215_","_9_101_214_","_9_101_213_","_9_101_212_","_9_101_211_","_9_101_210_","_9_101_209_","_9_101_208_","_9_101_207_","_9_101_206_","_9_101_205_","_9_101_204_","_9_101_203_","_9_101_202_","_9_101_201_","_9_101_200_","_9_101_199_","_9_101_198_","_9_101_196_","_9_101_197_","_9_101_195_","_9_194_","_9_101_223_","_9_101_224_","_9_101_225_","_9_102_226_","_9_102_227_","_9_102_228_","_9_102_229_","_9_102_230_","_9_102_231_","_9_102_232_","_9_102_233_","_9_102_234_","_9_102_235_","_9_102_236_","_9_102_237_","_9_102_238_","_9_102_239_","_9_102_240_","_9_102_241_","_9_102_242_","_9_102_243_","_9_102_244_","_9_102_245_","_9_102_246_","_9_102_247_","_9_102_248_","_9_102_249_","_9_102_250_","_9_102_251_","_9_102_252_","_9_102_253_","_9_102_254_","_9_102_255_","_9_102_256_") and status='enabled' order by created desc limit 0,50;

このクエリは、約 60,000 レコードで 0.38 秒かかります。これは非常に遅いと思います。Esplain は次のことを示しています。

+----+-------------+--------+------+----------------------------------+--------------------+---------+-------+-------+-----------------------------+
| id | select_type | table  | type | possible_keys                    | key                | key_len | ref   | rows  | Extra                       |
+----+-------------+--------+------+----------------------------------+--------------------+---------+-------+-------+-----------------------------+
|  1 | SIMPLE      | gc_ads | ref  | recount_index,home_page_featured | home_page_featured | 1       | const | 34347 | Using where; Using filesort |
+----+-------------+--------+------+----------------------------------+--------------------+---------+-------+-------+-----------------------------+

このクエリを実行すると (同じクエリですが、「and status='enabled'」が含まれていない場合、約 0.10 秒かかります。

select * from gc_ads use index(recount_index, home_page_featured) where c_path in ("_9_","_9_30_","_9_101_","_9_102_","_9_103_","_9_105_","_9_106_","_9_30_132_","_9_30_133_","_9_30_134_","_9_30_135_","_9_30_136_","_9_30_137_","_9_30_138_","_9_30_139_","_9_30_140_","_9_30_141_","_9_30_142_","_9_30_143_","_9_30_144_","_9_30_145_","_9_30_146_","_9_30_147_","_9_30_148_","_9_30_149_","_9_30_150_","_9_30_151_","_9_30_152_","_9_30_153_","_9_30_154_","_9_30_155_","_9_30_156_","_9_30_157_","_9_30_158_","_9_30_159_","_9_30_160_","_9_30_161_","_9_30_162_","_9_101_222_","_9_101_221_","_9_101_220_","_9_101_219_","_9_101_218_","_9_101_217_","_9_101_216_","_9_101_215_","_9_101_214_","_9_101_213_","_9_101_212_","_9_101_211_","_9_101_210_","_9_101_209_","_9_101_208_","_9_101_207_","_9_101_206_","_9_101_205_","_9_101_204_","_9_101_203_","_9_101_202_","_9_101_201_","_9_101_200_","_9_101_199_","_9_101_198_","_9_101_196_","_9_101_197_","_9_101_195_","_9_194_","_9_101_223_","_9_101_224_","_9_101_225_","_9_102_226_","_9_102_227_","_9_102_228_","_9_102_229_","_9_102_230_","_9_102_231_","_9_102_232_","_9_102_233_","_9_102_234_","_9_102_235_","_9_102_236_","_9_102_237_","_9_102_238_","_9_102_239_","_9_102_240_","_9_102_241_","_9_102_242_","_9_102_243_","_9_102_244_","_9_102_245_","_9_102_246_","_9_102_247_","_9_102_248_","_9_102_249_","_9_102_250_","_9_102_251_","_9_102_252_","_9_102_253_","_9_102_254_","_9_102_255_","_9_102_256_") order by created desc limit 0,50;

Explain は次のことを示しています。

+----+-------------+--------+-------+---------------+---------------+---------+------+-------+-----------------------------+
| id | select_type | table  | type  | possible_keys | key           | key_len | ref  | rows  | Extra                       |
+----+-------------+--------+-------+---------------+---------------+---------+------+-------+-----------------------------+
|  1 | SIMPLE      | gc_ads | range | recount_index | recount_index | 73      | NULL | 14293 | Using where; Using filesort |
+----+-------------+--------+-------+---------------+---------------+---------+------+-------+-----------------------------+

そして、「order by ...」なしでクエリを実行すると、非常に高速です(0.01秒):

select * from gc_ads use index(recount_index, home_page_featured) where c_path in ("_9_","_9_30_","_9_101_","_9_102_","_9_103_","_9_105_","_9_106_","_9_30_132_","_9_30_133_","_9_30_134_","_9_30_135_","_9_30_136_","_9_30_137_","_9_30_138_","_9_30_139_","_9_30_140_","_9_30_141_","_9_30_142_","_9_30_143_","_9_30_144_","_9_30_145_","_9_30_146_","_9_30_147_","_9_30_148_","_9_30_149_","_9_30_150_","_9_30_151_","_9_30_152_","_9_30_153_","_9_30_154_","_9_30_155_","_9_30_156_","_9_30_157_","_9_30_158_","_9_30_159_","_9_30_160_","_9_30_161_","_9_30_162_","_9_101_222_","_9_101_221_","_9_101_220_","_9_101_219_","_9_101_218_","_9_101_217_","_9_101_216_","_9_101_215_","_9_101_214_","_9_101_213_","_9_101_212_","_9_101_211_","_9_101_210_","_9_101_209_","_9_101_208_","_9_101_207_","_9_101_206_","_9_101_205_","_9_101_204_","_9_101_203_","_9_101_202_","_9_101_201_","_9_101_200_","_9_101_199_","_9_101_198_","_9_101_196_","_9_101_197_","_9_101_195_","_9_194_","_9_101_223_","_9_101_224_","_9_101_225_","_9_102_226_","_9_102_227_","_9_102_228_","_9_102_229_","_9_102_230_","_9_102_231_","_9_102_232_","_9_102_233_","_9_102_234_","_9_102_235_","_9_102_236_","_9_102_237_","_9_102_238_","_9_102_239_","_9_102_240_","_9_102_241_","_9_102_242_","_9_102_243_","_9_102_244_","_9_102_245_","_9_102_246_","_9_102_247_","_9_102_248_","_9_102_249_","_9_102_250_","_9_102_251_","_9_102_252_","_9_102_253_","_9_102_254_","_9_102_255_","_9_102_256_") limit 0,50;

Explain は次のことを示しています。

+----+-------------+--------+-------+---------------+---------------+---------+------+-------+-------------+
| id | select_type | table  | type  | possible_keys | key           | key_len | ref  | rows  | Extra       |
+----+-------------+--------+-------+---------------+---------------+---------+------+-------+-------------+
|  1 | SIMPLE      | gc_ads | range | recount_index | recount_index | 73      | NULL | 14293 | Using where |
+----+-------------+--------+-------+---------------+---------------+---------+------+-------+-------------+    

このクエリの正しいインデックスを作成する必要があると思いますが、この問題への取り組みを開始する方法が本当にわかりません。

4

2 に答える 2

1

これはあなたのクエリです:

select *
from gc_ads
where c_path in (. . .) and status='enabled'
order by created desc limit 0,50;

where句の条件はinand です。最適なインデックスはgc_ads(status, c_path, created). このwhere句では、最初の 2 つの要素を使用できます。はorder by最後の 1 つを使用できます。

recount_index前に 2 つの追加要素があるため、 は正しくありませんstatus

于 2013-09-05T21:40:31.783 に答える
0

経験則として、ほとんどのクエリで比較 (WHERE セクション、JOIN セクションなど) に使用される列にインデックスを作成します。これは、定期的に実行される最も複雑なクエリ (つまり、複数の結合) に含まれる列にも当てはまります。

あなたのSQLを見て、最善の解決策は、3つの列にまとめてインデックスを作成することだと思います.「c_path」と「status」は、比較に参加する列であるため)、および「作成済み」(ソート基準である値を保持しているため)。

ORDER BY クエリ部分の列をインデックスに含めることは必ずしも賢明ではありませんが、あなたの場合はかなり合理的です。ここでは、インデックス作成と ORDER BY について詳しく読むことをお勧めします。ここでは、なぜそれが理にかなっているか、理にかなっていないかを説明しています。

于 2013-09-05T21:41:22.400 に答える