2009-10-23 10 views
7

私は450000行のニュースがいっぱいのテーブルを持っています。 テーブルスキーマは、このようなものです:Mysqlのインデックス構成

CREATE TABLE IF NOT EXISTS `news` (
    `id` int(11) NOT NULL auto_increment, 
    `cat_id` int(11) NOT NULL, 
    `title` tinytext NOT NULL, 
    `content` text NOT NULL, 
    `date` int(11) NOT NULL, 
    `readcount` int(11) NOT NULL default '0', 
    PRIMARY KEY (`id`), 
    KEY `cat_id` (`cat_id`), 
    KEY `cat_id_2` (`cat_id`,`id`), 
    KEY `cat_id_date` (`cat_id`,`date`) 
) ENGINE=MyISAM DEFAULT CHARSET=latin5 AUTO_INCREMENT=462679 ; 

私はページのためにいくつかのニュースを取るために、以下のようなSQLコマンドを実行すると、「X」カテゴリページのxが100を超えている場合には、15秒以上かかります。

select * news where cat_id='4' order by id desc limit 150000,10; 

説明この質問を書いている間、私はまた、このような、より単純なSQLクエリをチェックし、それがまた分に近くかかった

をそのは、「どこで」使用していることを示しており、インデックス「cat_id_2」:

select * from haberler order by id desc limit 40000,10; 

SQLは、それはほんの数ミリ秒かかり、次のいずれかのようである場合:

select * from haberler order by id desc limit 20,10; 

私のmy.cnf設定は、このようなものです:

skip-locking 
skip-innodb 
query_cache_limit=1M 
query_cache_size=256M 
query_cache_type=1 
max_connections=30 
interactive_timeout=600000 
#wait_timeout=5 
#connect_timeout=5 
thread_cache_size=384 
key_buffer=256M 
join_buffer=4M 
max_allowed_packet=16M 
table_cache=1024 
record_buffer=1M 
sort_buffer_size=64M 
read_buffer_size=16M 
max_connect_errors=10 
# Try number of CPU's*2 for thread_concurrency 
thread_concurrency=2 
myisam_sort_buffer_size=128M 
long_query_time   = 1 
log_slow_queries  = /var/log/mysql/mysql-slow.log 
max_heap_table_size=512M 

ウェブサイトはcore2duo上で実行されています2GBのRAMを搭載。 私はこの問題がsort_buffer_sizeによって引き起こされるかもしれないとは思いますが、わかりません。ありがとうございます。

+0

はまたあなたのインデックスも、あなたがこの側面に見ませんでしたか? –

+0

あなたの質問には多くの不一致があります。あなたはそれをもっと明確にするために編集できますか? –

+0

これは固定されていなければなりません。テーブルに使われている名前は本来トルコ語ですが、英語の一部を翻訳するのを忘れてしまったようです。 私の悪い英語のために申し訳ありません。 – intacto

答えて

17

更新:

が問題のより詳細な分析のために私のブログでこの記事を参照してください。


あなたがLIMIT 150000, 10のようなものを発行し、 MySQLはこれらを通過する必要があります。150,000と記録し、次に10を見つけます。

MySQLではインデックスの移動が遅いです。

また、MySQLは、後で行検索を行うことができません。

あなたがORDER BY id LIMIT 100000, 10をすれば理論的には、そのインデックスを満たすだけ10行を検索し、それらを返す、100000から100010に値を見つけるためにインデックスを使用するのに十分です。

MySQLを除くすべての主要なシステムは、それを認識しており、値が実際に返される場合にのみ行を見ます。

MySQLただし、すべての行を検索します。このようクエリを書き換える

試してみてください。

SELECT news.* 
FROM (
     SELECT id 
     FROM news 
     WHERE cat_id='4' 
     ORDER BY 
       id DESC 
     LIMIT 150000, 10 
     ) o 
JOIN news 
ON  news.id = o.id 
+0

あなたのクエリははるかに高速に動作しているようだが、理由を理解できない。 理由を教えていただけますか? – intacto

+1

後半の行の参照、私は私の記事でこれを説明した。私のクエリは、テーブル自体から '10'レコードのみを選択し、元のクエリはすべての '150,000'レコードを選択して破棄します。今晩は私がブログ記事を作っていきます。それについてはもっと詳しく説明します。 – Quassnoi

+0

だから、ちょうどidを取るともっと速くなります。ありがとうございます。 – intacto

関連する問題