अनुक्रमित डेटाटाइम कॉलम का उपयोग करके MySQL प्रदर्शन समस्या


15

मैंने अब लगभग एक घंटे के लिए निम्नलिखित समस्या को हल करने की कोशिश की और अभी भी इसके साथ आगे नहीं मिला।

ठीक है, मेरे पास एक मेज है (MyISAM):

+---------+-------------+------+-----+-------------------+----------------+
| Field   | Type        | Null | Key | Default           | Extra          |
+---------+-------------+------+-----+-------------------+----------------+
| id      | int(11)     | NO   | PRI | NULL              | auto_increment |
| http    | smallint(3) | YES  | MUL | 200               |                |
| elapsed | float(6,3)  | NO   |     | NULL              |                |
| cached  | tinyint(1)  | YES  |     | NULL              |                |
| ip      | int(11)     | NO   |     | NULL              |                |
| date    | timestamp   | NO   | MUL | CURRENT_TIMESTAMP |                |
+---------+-------------+------+-----+-------------------+----------------+

कृपया अनुक्रमणिका पर ध्यान न दें, मैं एक समाधान खोजने की कोशिश कर रहा हूं। अब, यहाँ मेरा प्रश्न है।

SELECT http,
COUNT( http )  AS count 
FROM reqs
WHERE DATE(date) >= cast(date_sub(date(NOW()),interval 24 hour) as datetime)
GROUP BY http
ORDER BY count;

तालिका आने वाले वेब अनुरोधों के बारे में जानकारी संग्रहीत कर रही है ताकि यह एक बड़ा डेटाबेस हो।

+-----------+
| count(id) |
+-----------+
|    782412 |
+-----------+

ध्यान दें कि प्राथमिक कुंजी सेट करने का कोई बेहतर तरीका नहीं है क्योंकि आईडी कॉलम मेरे पास एकमात्र विशिष्ट पहचानकर्ता होगा। उपर्युक्त क्वेरी को चलाने में लगभग 0.6-1.6 सेकंड लगते हैं।

कौन सा सूचकांक चतुर होगा? मुझे लगा कि इंडेक्सिंग की तारीख मुझे "खराब" कार्डिनैलिटी देगी और इस तरह MySQL इसका उपयोग नहीं करेगी। http भी एक बुरा विकल्प है क्योंकि इसमें लगभग 20 विभिन्न संभावित मूल्य हैं।

मदद के लिये शुक्रिया!

अपडेट 1 मैंने ypercube के सुझाव के अनुसार (http, date) पर एक इंडेक्स जोड़ा है :

mysql> CREATE INDEX httpDate ON reqs (http, date);

और उसकी क्वेरी का उपयोग किया, लेकिन इसने उतना ही बुरा प्रदर्शन किया। जोड़ा गया सूचकांक:

+-------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment |
+-------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
| reqs  |          0 | PRIMARY  |            1 | id          | A         |      798869 |     NULL | NULL   |      | BTREE      |         |
| reqs  |          1 | httpDate |            1 | http        | A         |          19 |     NULL | NULL   | YES  | BTREE      |         |
| reqs  |          1 | httpDate |            2 | date        | A         |       99858 |     NULL | NULL   |      | BTREE      |         |
+-------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+

और व्याख्या

+----+--------------------+-------+-------+---------------+----------+---------+------+-------+-----------------------------------------------------------+
| id | select_type        | table | type  | possible_keys | key      | key_len | ref  | rows  | Extra                                                     |
+----+--------------------+-------+-------+---------------+----------+---------+------+-------+-----------------------------------------------------------+
|  1 | PRIMARY            | r     | range | NULL          | httpDate | 3       | NULL |    20 | Using index for group-by; Using temporary; Using filesort |
|  2 | DEPENDENT SUBQUERY | ri    | ref   | httpDate      | httpDate | 3       | func | 41768 | Using where; Using index                                  |
+----+--------------------+-------+-------+---------------+----------+---------+------+-------+-----------------------------------------------------------+

MySQL सर्वर संस्करण:

mysql> SHOW VARIABLES LIKE "%version%";
+-------------------------+---------------------+
| Variable_name           | Value               |
+-------------------------+---------------------+
| protocol_version        | 10                  |
| version                 | 5.1.73              |
| version_comment         | Source distribution |
| version_compile_machine | x86_64              |
| version_compile_os      | redhat-linux-gnu    |
+-------------------------+---------------------+
5 rows in set (0.00 sec)

क्या आप mysql वर्जन भी जोड़ सकते हैं और टेबल का इंजन क्या है? (मायिसम या इनोडब)
ypercube

MyISAM और 5.1.73 - अब पोस्ट में सभी विवरण।
रॉबिन हेलर

मुझे डर है कि httpस्तम्भ अशक्त होने के साथ यह करना पड़ सकता है । अगर मुझे समय मिल गया तो मैं कल जांच करूंगा।
ypercube y

मुझे डर है कि यह http कॉलम के अशक्त होने के साथ हो सकता है। अगर मुझे समय मिल गया तो मैं कल जांच करूंगा। आप एक समान तालिका बनाकर (उसके साथ छोड़कर http NOT NULL) और सभी डेटा को कॉपी करके (निश्चित रूप से http NULL के साथ पंक्तियों को छोड़कर) परीक्षण कर सकते हैं ।
ypercubeᵀᴹ

इसे नॉट में बदलना (जो पूरी तरह से संभव है, टेबल बनाते समय मैंने इसे ज्यादा दिमाग नहीं लगाया) क्वेरी के लिए ~ 1s - 1.6s के लिए प्रदर्शन को बढ़ाया (मेरी क्वेरी)। आपके प्रयास के लिए अब तक धन्यवाद।
रॉबिन हेलर

जवाबों:


10

मेरे तीन सुझाव हैं

प्रश्न # 1: क्वेरी को फिर से लिखें

आपको निम्नानुसार क्वेरी को फिर से लिखना चाहिए

SELECT http,
COUNT( http )  AS count 
FROM reqs
WHERE date >= ( DATE(NOW() - INTERVAL 1 DAY) + INTERVAL 0 SECOND )
GROUP BY http
ORDER BY count;

या

SELECT * FROM
(
    SELECT http,
    COUNT( http )  AS count 
    FROM reqs
    WHERE date >= ( DATE(NOW() - INTERVAL 1 DAY) + INTERVAL 0 SECOND )
    GROUP BY http
) A ORDER BY count;

WH समान चिह्न के दोनों ओर फ़ंक्शन नहीं होना चाहिए। बराबर चिह्न के बाईं ओर दिनांक होने से क्वेरी ऑप्टिमाइज़र के लिए इसके विरुद्ध अनुक्रमणिका का उपयोग करना आसान हो जाता है।

सहायता # 2: सहायक सूचकांक

मैं एक अलग सूचकांक भी सुझाऊंगा

ALTER TABLE reqs ADD INDEX date_http_ndx (date,http); -- not (http,date) 

मैं स्तंभों के इस क्रम का सुझाव देता हूं क्योंकि dateप्रविष्टियां सभी सूचकांक में सन्निहित होंगी। फिर, क्वेरी बस httpअंतराल लंघन के बिना मान एकत्र करता है http

उत्तर # 3: बड़ा कुंजी बफर (वैकल्पिक)

MyISAM केवल इंडेक्स कैशिंग का उपयोग करता है। चूंकि क्वेरी को .MYDफ़ाइल को स्पर्श नहीं करना चाहिए , इसलिए आपको थोड़ा बड़ा MyISAM कुंजी बफर का उपयोग करना चाहिए।

इसे 256M पर सेट करने के लिए

SET @newsize = 1024 * 1024 * 256;
SET GLOBAL key_buffer_size = @newsize;

फिर, इसे अंदर सेट करें my.cnf

[mysqld]
key_buffer_size = 256M

MySQL का पुनरारंभ आवश्यक नहीं है

कोशिश करो !!!


आपने मेरे द्वारा दिए गए प्रश्नों की कोशिश की। # 1 ने दूसरे सुझाव या मेरे खुद के बारे में जितना अच्छा प्रदर्शन किया, दूसरा वास्तव में उतना ही बुरा रहा। सपोर्टिंग इंडेक्स के लिए समान बात - प्रदर्शन ड्रॉप को लगभग 75 प्रतिशत करें। मैं अब बड़ी कुंजी बफर की कोशिश करने जा रहा हूँ, वैसे भी धन्यवाद!
रॉबिन हेलर

मैंने आपके उत्तर को स्वीकार कर लिया है, हालांकि यह समस्या को ठीक नहीं करता है, एक बड़े कुंजी बफर के साथ हालांकि यह कुछ बेहतर प्रदर्शन करता है। इसे बंद करना क्योंकि यह दिए गए सभी का सबसे अच्छा समाधान है। धन्यवाद!
रोबिन हेलर

सुझाव # 2 को काम करने के लिए, क्वेरी में "USE INDEX" या "FORCE INDEX" जोड़ना आवश्यक हो सकता है, कम से कम यही है कि मुझे एक सूचकांक बनाने के बाद अपनी क्वेरी को तेज करने के लिए क्या करना था।
जोहानो फ़िएरा

-2

अपने दिनांक स्तंभ प्रकार को पूर्णांक में बदलें। पूर्णांक में यूनिक्स की तारीख के रूप में तारीख स्टोर करें। टाइमस्टैम्प एक इंट की तुलना में बहुत बड़ा है। आपको इसमें से कुछ धमाके होने चाहिए।


3
क्या तुम मजाक कर रहे हो? दोनों INTऔर TIMESTAMP4 बाइट्स की जरूरत है।
ypercube y

3
ओ.टी. का उल्लेख नहीं है कि जब आप दिनांक या टाइमस्टैम्प को पूर्णांक के रूप में संग्रहीत कर रहे हैं, तो आप सभी डेटाटाइम कार्य खो देते हैं।
ypercube y
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.