2011-05-23 13 views
10

मैं डेटाटाइम कॉलम द्वारा एक MySQL तालिका को विभाजित करना चाहता हूं। एक दिन एक partition.The तालिका स्क्रिप्ट बनाने के इस तरह है:डेटाटाइम कॉलम द्वारा तालिका को कैसे विभाजित करें?

CREATE TABLE raw_log_2011_4 (
    id bigint(20) NOT NULL AUTO_INCREMENT, 
    logid char(16) NOT NULL, 
    tid char(16) NOT NULL, 
    reporterip char(46) DEFAULT NULL, 
    ftime datetime DEFAULT NULL, 
    KEY id (id) 
) ENGINE=InnoDB AUTO_INCREMENT=286802795 DEFAULT CHARSET=utf8 
PARTITION BY hash (day(ftime)) partitions 31; 

लेकिन जब मैं कुछ day.It partition.The चयन बयान पता नहीं लगा सके की डेटा का चयन इस तरह है:

explain partitions select * from raw_log_2011_4 where day(ftime) = 30; 

जब मैं एक और कथन का उपयोग करता हूं, तो यह विभाजन का पता लगा सकता है, लेकिन मैंने कुछ दिन के डेटा का चयन नहीं किया है।

explain partitions select * from raw_log_2011_4 where ftime = '2011-03-30'; 

क्या कोई मुझे बताता है कि मैं कुछ दिन का डेटा कैसे चुन सकता हूं और विभाजन का उपयोग कर सकता हूं। धन्यवाद!

उत्तर

7

हाय आप तालिका की परिभाषा में गलत विभाजन कर रहे हैं तालिका परिभाषा इस चाहते हैं:

CREATE TABLE raw_log_2011_4 (
    id bigint(20) NOT NULL AUTO_INCREMENT, 
    logid char(16) NOT NULL, 
    tid char(16) NOT NULL, 
    reporterip char(46) DEFAULT NULL, 
    ftime datetime DEFAULT NULL, 
    KEY id (id) 
) ENGINE=InnoDB AUTO_INCREMENT=286802795 DEFAULT CHARSET=utf8 
PARTITION BY hash (TO_DAYS(ftime)) partitions 31; 

और अपने चयन कमांड यह होगी:

explain partitions 
    select * from raw_log_2011_4 where TO_DAYS(ftime) = '2011-03-30'; 

उपरोक्त आदेश सभी का चयन करेंगे दिनांक आवश्यक है, जैसे कि आप TO12AYS कमांड का उपयोग

mysql> SELECT TO_DAYS(950501); 
     -> 728779 
mysql> SELECT TO_DAYS('2007-10-07'); 
     -> 733321 

क्यों उपयोग करें ई TO_DAYS MySQL अनुकूलक विभाजन छंटाई प्रयोजनों के लिए दो-आधारित कार्यों के रूप में पहचान लेंगे: 1.TO_DAYS() 2.YEAR()

और यह आपकी समस्या का समाधान होगा ..

+0

'^ 1' क्या होगा यदि तालिका में वर्षों की संख्या अज्ञात है, चाहे 'हैश (वर्ष (ftime)) का हिस्सा काम करेगा? –

1

मैं अभी हाल ही में पढ़ा http://dev.mysql.com/tech-resources/articles/mysql_55_partitioning.html पर, इस से संबंधित एक MySQL ब्लॉग पोस्ट।

संस्करण आदेश दिनांक के आधार पर विभाजन करने के लिए 5.1 की आवश्यकता विशेष जिमनास्टिक से पहले। ऊपर दिया गया लिंक इस पर चर्चा करता है और उदाहरण दिखाता है।

संस्करण 5.5 और बाद आप इस तरह की तारीख और तारों के रूप में गैर-अंकीय मान का उपयोग कर प्रत्यक्ष विभाजन करने की अनुमति दी।

HASH द्वारा
12

विभाजन, datetime कॉलम के साथ एक बहुत बुरा विचार है, क्योंकि यह partition pruning उपयोग नहीं कर सकते। MySQL दस्तावेज़ों से:

प्रुनिंग केवल द्वारा विभाजित तालिकाओं के पूर्णांक कॉलम पर उपयोग किया जा सकता है HASH या कुंजी। उदाहरण के लिए, तालिका टी -4 पर इस क्वेरी छंटाई उपयोग नहीं कर सकते क्योंकि जन्म तिथि एक तिथि कॉलम है:

SELECT * FROM t4 WHERE dob >= '2001-04-14' AND dob <= '2005-10-15'; 

लेकिन अगर एक INT कॉलम में तालिका भंडार साल मूल्यों, तो एक क्वेरी होने कहां year_col > = 2001 और वर्ष_col < = 2005 काटा जा सकता है।

तो आप छंटनी का उपयोग करने के लिए अतिरिक्त INTEGER कॉलम में TO_DAYS (DATE()) के मान को संग्रहीत कर सकते हैं।

CREATE TABLE raw_log_2011_4 (
    id bigint(20) NOT NULL AUTO_INCREMENT, 
    logid char(16) NOT NULL, 
    tid char(16) NOT NULL, 
    reporterip char(46) DEFAULT NULL, 
    ftime datetime DEFAULT NULL, 
    KEY id (id) 
) ENGINE=InnoDB AUTO_INCREMENT=286802795 DEFAULT CHARSET=utf8 
    PARTITION BY RANGE(TO_DAYS(datetime)) (
    PARTITION p20110401 VALUES LESS THAN (TO_DAYS('2011-04-02')), 
    PARTITION p20110402 VALUES LESS THAN (TO_DAYS('2011-04-03')), 
    PARTITION p20110403 VALUES LESS THAN (TO_DAYS('2011-04-04')), 
    PARTITION p20110404 VALUES LESS THAN (TO_DAYS('2011-04-05')), 
    ... 
    PARTITION p20110426 VALUES LESS THAN (TO_DAYS('2011-04-27')), 
    PARTITION p20110427 VALUES LESS THAN (TO_DAYS('2011-04-28')), 
    PARTITION p20110428 VALUES LESS THAN (TO_DAYS('2011-04-29')), 
    PARTITION p20110429 VALUES LESS THAN (TO_DAYS('2011-04-30')), 
    PARTITION future VALUES LESS THAN MAXVALUE 
); 

अब निम्न क्वेरी केवल विभाजन p20110403 का उपयोग करेगा::

SELECT * FROM raw_log_2011_4 WHERE ftime = '2011-04-03'; 
+0

मैं विभाजन के बारे में सीख रहा हूं, 'WHERE' कथन में 'DATE_FORMAT()' का उपयोग क्यों नहीं किया जाता है? – enchance

+0

@ स्टेक्स - शायद आप का मतलब है 'कहां ftime> =' 2011-04-03 'और ftime <' 2011-04-03 '+ अंतराल 1 दिन'। –

0

CHAR का उपयोग न करें, VARCHAR का उपयोग

एक अन्य विकल्प रेंज विभाजन का प्रयोग है। इससे बहुत सी जगह बच जाएगी, इसलिए I/O कम हो जाएगी, इसलिए प्रश्नों को तेज करें।

reporterip: (46) आईपी पते, यहां तक ​​कि आईपीवी 6 के लिए अनावश्यक रूप से बड़ा है। आगे की चर्चा के लिए My blog देखें, जिसमें इसे 16 बाइट्स तक कम करने के तरीके शामिल हैं।

PARTITION BY RANGE(TO_DAYS(...)) @Steyx के रूप में सुझाव दिया गया है, लेकिन इसमें 50 से अधिक विभाजन नहीं हैं। आपके पास जितने अधिक विभाजन हैं, धीमे प्रश्न पूछते हैं, "छंटनी" के बावजूद। HASH विभाजन अनिवार्य रूप से बेकार है।

More discussion of partitioning, especially the type you are looking at। इसमें समय के साथ विभाजन के स्लाइडिंग सेट के लिए कोड शामिल है।

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