4

私はこのように数えたいと思っています(例として、実際には犬を数えていません):

SELECT COUNT(*)
FROM dogs AS d INNER JOIN races AS r ON d.race_id = r.race_id
    LEFT INNER colors AS c ON c.color_id = r.color_id
WHERE d.deceased = 'N'

MyISAM テーブルに 130,000 匹の犬がいます。Races には 1,500 のレコードがあり、9 列の InnoDB テーブルです。colors には 83 のレコードがあり、これも InnoDB で、2 つの列 (id、name) があります。*_id 列はすべて主キーです。「外部」キーの Dogs.race_id と races.color_id にインデックスがあり、dogs.deceased にインデックスがあります。上記の列はいずれも にすることはできませんNULL

# mysql --version
mysql  Ver 14.12 Distrib 5.0.51a, for debian-linux-gnu (i486) using readline 5.2

問題は次のとおりです。私の PhpMyAdmin では、このクエリに 1.8 秒かかり ( を使用SQL_NO_CACHE)、カウント結果は 64,315 です。orに変更COUNT(*)すると、クエリの実行に 1.8 秒かかり、同じ結果が得られます。COUNT(d.dog_id)COUNT(d.deceased)

しかし、 を削除しCOUNT()SELECT *orSELECT dog_idを実行すると、実行に約 0.004 秒かかります (その後、 などで結果をカウントしますmysql_num_rows())。

どうすればいいの?また、どうすればCOUNT()仕事を速くすることができますか?

編集:EXPLAIN以下を追加

EXPLAIN SELECT COUNT(*)
FROM dogs AS d INNER JOIN races AS r ON d.race_id = r.race_id
    INNER JOIN colors AS c ON c.color_id = r.color_id
WHERE d.deceased = 'N'

私に与えます:

+----+-------------+-------+-------+------------------+----------+---------+----------------------+------+-------------+
| id | select_type | table | type  | possible_keys    | key      | key_len | ref                  | rows | Extra       |
+----+-------------+-------+-------+------------------+----------+---------+----------------------+------+-------------+
|  1 | SIMPLE      | c     | index | color_id         | color_id | 4       | NULL                 |   83 | Using index | 
|  1 | SIMPLE      | r     | ref   | PRIMARY,color_id | color_id | 4       | database.c.color_id  |   14 | Using index | 
|  1 | SIMPLE      | d     | ref   | race_id,deceased | race_id  | 4       | database.r.race_id   |  123 | Using where | 
+----+-------------+-------+-------+------------------+----------+---------+----------------------+------+-------------+
4

3 に答える 3

1

MySQL Optimizer は必要な場合にのみフル テーブル スキャンを実行します。これは、列が NULL になる可能性があるためです。つまり、列が NOT NULL として定義されていない場合、列に NULL 値が含まれる可能性があるため、MySQL は検出するためにテーブル スキャンを実行する必要があります。あなたの列がd.dog_idヌル可能なら?null 許容ではない別の列でカウントを実行してみてください。これにより、count(*) よりも優れたパフォーマンスが得られるはずです。

于 2013-04-09T09:50:15.120 に答える
0

にインデックスを設定しdogs.deceasedて使用してみてくださいSELECT COUNT(*) ... USE INDEX my_index_name

于 2013-04-09T09:51:51.640 に答える