2009-10-23 19 views
7

मेरे पास 450000 पंक्तियों से भरा एक टेबल है। तालिका स्कीमा इस तरह है:माइस्क्ल इंडेक्स कॉन्फ़िगरेशन

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 ; 

जब मैं नीचे की तरह एक एसक्यूएल आदेश चला एक पेज "x" श्रेणी पेज के यह 15 से अधिक सेकंड लेता है के लिए कुछ खबर लेने के लिए अगर एक्स 100 से अधिक है:

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

शो है कि इसके उपयोग करते हुए "जहाँ" और सूचकांक "cat_id_2"

हालांकि यह सवाल मैं भी इस तरह एक और अधिक सरल एसक्यूएल क्वेरी जाँच की लेखन और यह भी एक मिनट के पास ले गया समझाने

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

अगर एसक्यूएल के बाद एक यह बस कुछ मिलीसेकेंड की तरह है:

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 पर चल रहा है 2 जीबी रैम के साथ। मुझे लगता है कि समस्या sort_buffer_size के कारण हो सकती है लेकिन मुझे यकीन नहीं है। अग्रिम धन्यवाद।

+0

भी अपने अनुक्रमित हो सकता है, तो आप इस पहलू पर गौर किया है? –

+0

आपके प्रश्न में कई असंगतताएं हैं, कृपया इसे और स्पष्ट करने के लिए आप इसे संपादित कर सकते हैं? –

+0

अब इसे ठीक किया जाना चाहिए, तालिका में उपयोग किए जाने वाले नाम मूल रूप से तुर्की थे, ऐसा लगता है जैसे मैं उनमें से कुछ को अंग्रेजी में अनुवाद करना भूल गया था। रास्ते में मेरी खराब अंग्रेजी के लिए खेद है। – intacto

उत्तर

17

अद्यतन:

समस्या का अधिक विस्तृत विश्लेषण के लिए अपने ब्लॉग में इस लेख देखें:


जब आप LIMIT 150000, 10 की तरह कुछ जारी, इसका मतलब है कि MySQL इनको पार करना चाहिएरिकॉर्ड और अगले 10 खोजें।

सूचकांक का ट्रैवर्स MySQL में धीमा है।

इसके अलावा, MySQL देर से पंक्ति लुकअप करने में सक्षम नहीं है।

सैद्धांतिक रूप से, अगर आप ORDER BY id LIMIT 100000, 10 करते हैं, यह 100000 से 100010 के मूल्यों को खोजने के सूचकांक का उपयोग करने के, तो केवल 10 पंक्तियों कि सूचकांक को पूरा करने और उन्हें वापस जाने को देखने के लिए पर्याप्त है।

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

इसलिए बस आईडी लेना इसे तेज बनाता है, धन्यवाद, धन्यवाद .. – intacto

संबंधित मुद्दे