2009-07-28 11 views
1

を持っていません最初と最後の結合で索引を使用できることが期待されます。あなたが見ることができるように、それはしません。私のMySQLのインデックスは、私は次のクエリを持っている任意の効果

最初は計算された日付とは関係がありますが、日付フィルタがなくてもインデックスは使用されません。私はインデックスのいくつかのバリエーションを試みたが、私ははるかに多くを取得していません。私はここで何が欠けていますか?

関連するテーブルのインデックスは次のとおりです。

ALTER TABLE exhibitions ADD INDEX(slug); 
ALTER TABLE exhibitions ADD INDEX(venue_id, ends); 

ALTER TABLE temperatures ADD INDEX(ref); 

そして、要求され、展覧会だけでなく、テーブルのクエリを作成するなど:

CREATE TABLE `exhibitions` (
    `id` char(36) NOT NULL, 
    `clue` char(6) NOT NULL DEFAULT '', 
    `venue_id` char(36) NOT NULL, 
    `name` varchar(255) NOT NULL, 
    `slug` varchar(255) NOT NULL, 
    `description` text, 
    `starts` date DEFAULT NULL, 
    `ends` date DEFAULT NULL, 
    `url` varchar(255) DEFAULT NULL, 
    `user_id` char(36) NOT NULL, 
    `featured` tinyint(1) NOT NULL DEFAULT '0', 
    `permanent` tinyint(1) unsigned NOT NULL DEFAULT '0', 
    `active` tinyint(1) unsigned NOT NULL DEFAULT '1', 
    `cidn` varchar(255) DEFAULT NULL, 
    `created` datetime NOT NULL, 
    `modified` datetime NOT NULL, 
    PRIMARY KEY (`id`), 
    KEY `slug` (`slug`), 
    KEY `cidn` (`cidn`), 
    KEY `venue_id` (`venue_id`,`ends`), 
    KEY `venue_id2` (`venue_id`), 
    FULLTEXT KEY `name` (`name`,`description`,`url`) 
) ENGINE=MyISAM AUTO_INCREMENT=4 DEFAULT CHARSET=utf8; 

を追加しまし統計:結果を更新しました

mysql> SELECT * 
-> FROM information_schema.statistics 
-> WHERE UPPER(table_name) = UPPER('temperatures') 
->   AND UPPER(column_name) = UPPER('ref'); 
+---------------+--------------+--------------+------------+--------------+------------+--------------+-------------+-----------+-------------+----------+--------+----------+------------+---------+ 
| TABLE_CATALOG | TABLE_SCHEMA | TABLE_NAME | NON_UNIQUE | INDEX_SCHEMA | INDEX_NAME | SEQ_IN_INDEX | COLUMN_NAME | COLLATION | CARDINALITY | SUB_PART | PACKED | NULLABLE | INDEX_TYPE | COMMENT | 
+---------------+--------------+--------------+------------+--------------+------------+--------------+-------------+-----------+-------------+----------+--------+----------+------------+---------+ 
| NULL   | narb   | temperatures |   0 | narb   | unique_ref |   1 | ref   | A   |  2655 |  NULL | NULL |   | BTREE  |   | 
| NULL   | narb   | temperatures |   1 | narb   | ref  |   1 | ref   | A   |  2655 |  NULL | NULL |   | BTREE  |   | 
+---------------+--------------+--------------+------------+--------------+------------+--------------+-------------+-----------+-------------+----------+--------+----------+------------+---------+ 
2 rows in set (0.02 sec) 

クアズノーの誇り:

mysql> EXPLAIN 
-> SELECT Exhibition.venue_id, Exhibition.name, Exhibition.slug, 
->   Venue.name, Venue.slug, Venue.location_id, 
->   Venue.id, Exhibition.id 
-> FROM exhibitions AS Exhibition 
-> LEFT JOIN 
->   venues AS Venue 
-> ON  Venue.id = Exhibition.venue_id 
-> LEFT JOIN 
->   temperatures AS Temperature FORCE INDEX (unique_ref) 
-> ON  Temperature.ref = Exhibition.id 
-> WHERE Exhibition.active = '1' 
->   AND Exhibition.ends <= CURDATE() 
-> ORDER BY 
->   Temperature.temperature DESC 
-> LIMIT 5; 
+----+-------------+-------------+--------+---------------+---------+---------+--------------------------+------+----------------------------------------------+ 
| id | select_type | table  | type | possible_keys | key  | key_len | ref      | rows | Extra          | 
+----+-------------+-------------+--------+---------------+---------+---------+--------------------------+------+----------------------------------------------+ 
| 1 | SIMPLE  | Exhibition | ALL | NULL   | NULL | NULL | NULL      | 1536 | Using where; Using temporary; Using filesort | 
| 1 | SIMPLE  | Venue  | eq_ref | PRIMARY  | PRIMARY | 108  | narb.Exhibition.venue_id | 1 |            | 
| 1 | SIMPLE  | Temperature | ALL | NULL   | NULL | NULL | NULL      | 2662 |            | 
+----+-------------+-------------+--------+---------------+---------+---------+--------------------------+------+----------------------------------------------+ 
3 rows in set (0.00 sec) 

は、追加の温度のテーブルを作成します。

CREATE TABLE `temperatures` (
    `id` int(10) unsigned NOT NULL auto_increment, 
    `ref` char(36) NOT NULL, 
    `views` int(10) unsigned NOT NULL, 
    `ratings` int(10) unsigned NOT NULL, 
    `comments` int(10) unsigned NOT NULL, 
    `bookmarks` int(10) unsigned NOT NULL, 
    `tags` int(10) unsigned NOT NULL, 
    `collected` int(10) unsigned NOT NULL default '0', 
    `trips` int(10) unsigned NOT NULL, 
    `fans` int(10) unsigned NOT NULL, 
    `temperature` int(10) NOT NULL default '1000', 
    `created` datetime NOT NULL, 
    `modified` datetime NOT NULL, 
    PRIMARY KEY (`id`), 
    UNIQUE KEY `unique_ref` (`ref`), 
    KEY `ref` (`ref`) 
) ENGINE=MyISAM AUTO_INCREMENT=2743 DEFAULT CHARSET=latin1; 

答えて

2

は、このクエリの結果を投稿してくださいでした:

SELECT * 
FROM information_schema.statistics 
WHERE UPPER(table_name) = UPPER('temperatures') 
     AND UPPER(column_name) = UPPER('ref') 

アップデート3:temperaturesCHARACTER SET LATIN1のように定義されている間あなたのexhibitionテーブルは、CHARACTER SET UTF8のように定義されて

UTF8LATIN1に暗黙的に変換できないので、暗黙COLLATE UTF8は、それがunsargableインデックスが使用できなくなって、Temperature.refに添加されます。私は私のインデックスは、このクエリに対して正しいと思うが、私は」

ALTER TABLE temperatures MODIFY COLUMN ref CHAR(36) CHARACTER SET utf8 NOT NULL, CHARACTER SET utf8 
+1

完了!申し訳ありませんが少し時間がかかりましたが、その間NL – tijs

+0

に強制インデックスが追加されていましたが、どちらの効果もないようです... – tijs

+0

はテーブル作成クエリを追加しました... – tijs

1

あなたのインデックスがあなたの結合順序と一致して確認する必要があります。複数の条件または複数の結合を使用している場合、MySQLは一致するインデックスを探します。例えば:

のは、次のフィールドで設定インデックスがあるとしましょう:Exhibition.venue_id、Exhibition.active、Exhibition.ends

SELECT文が

SELECT fields FROM exhibitions WHERE Exhibition.venue_id > 10 AND Exhibition.active = 'T' AND Exhibition.ends < '2009/9/23' 

次に、あなたのインデックスである場合使用すべきです。条件の順序を変更すると、インデックスが使用されない可能性があります。これは、表示されている問題を引き起こす可能性があります。

また、アクティブなフィールドのインデックスがブール値である場合、非アクティブな展覧会より一般的にアクティブでない展示がない限り、検索に大きな価値はありません。大量のレコードがない場合、オプティマイザは、スキャンがより効率的であると判断するため、索引の使用を破棄することもあります。

私は10,000レコードを生成し、それを再実行します。まだインデックスを使用していないかどうかを確認してください。

-Chris

+0

temperaturesUTF8に変換、

SELECT Exhibition.venue_id, Exhibition.name, Exhibition.slug, Venue.name, Venue.slug, Venue.location_id, Venue.id, Exhibition.id FROM exhibitions AS Exhibition LEFT JOIN venues AS Venue ON Venue.id = Exhibition.venue_id LEFT JOIN temperatures AS Temperature FORCE INDEX (unique_ref) ON Temperature.ref = CAST(Exhibition.id AS CHAR CHARACTER SET latin1) WHERE Exhibition.active = '1' AND Exhibition.ends <= CURDATE() ORDER BY Temperature.temperature DESC LIMIT 5 

、または、より良い:あなたはこのようクエリを書き直すのいずれか必要

あなたはより多くのデータとそれがそれだったかどうかを確認してください – tijs

+0

あなたはcreate table sqlを投稿できますか?おそらく、あなたが作成した索引を見れば助けになるでしょう。 –

+0

がテーブルを作成しましたSQL – tijs

関連する問題