निम्न रेल क्वेरी धीमी क्वेरी लॉग में वापस फेंकती है:

Class ParserRun

scope :active, -> {
where(completed_at: nil)
  .joins('LEFT JOIN system_events ON parser_runs.id = system_events.parser_run_id')
  .where("system_events.created_at > '#{active_system_events_threshold}' OR parser_runs.created_at > '#{1.minute.ago.to_s(:db)}'")
}

मैं इसे कैसे अनुकूलित कर सकता हूं?

धीमी क्वेरी लॉग:

SELECT `parser_runs`.*
FROM `parser_runs`
INNER JOIN `system_events` ON `system_events`.`parser_run_id` = `parser_runs`.`id`
WHERE `parser_runs`.`type` IN ('DatasetParserRun')
  AND `parser_runs`.`completed_at` IS NULL
  AND (system_events.created_at <= '2017-08-05 04:03:09');

# Time: 170805  5:03:43

'शो क्रिएट टेबल parser_runs;' का आउटपुट

| parser_runs | CREATE TABLE `parser_runs` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`type` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
`customer_id` int(11) DEFAULT NULL,
`options` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
`completed_at` datetime DEFAULT NULL,
`created_at` datetime DEFAULT NULL,
`updated_at` datetime DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `index_parser_runs_on_customer_id` (`customer_id`)
) ENGINE=InnoDB AUTO_INCREMENT=143327 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci |

'शो क्रिएट टेबल system_events;' का आउटपुट

 | system_events | CREATE TABLE `system_events` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`log_level` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
`customer_id` int(11) DEFAULT NULL,
`classification` int(11) DEFAULT NULL,
`information` text COLLATE utf8_unicode_ci,
`created_at` datetime DEFAULT NULL,
`updated_at` datetime DEFAULT NULL,
`parser_run_id` int(11) DEFAULT NULL,
`notified` tinyint(1) DEFAULT '0',
`dataset_log_id` int(11) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `index_system_events_on_classification` (`classification`),
KEY `index_system_events_on_customer_id` (`customer_id`),
KEY `index_system_events_on_parser_run_id` (`parser_run_id`),
KEY `index_system_events_on_dataset_log_id` (`dataset_log_id`)
) ENGINE=InnoDB AUTO_INCREMENT=730539 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci |

व्याख्या का आउटपुट:

  EXPLAIN for: SELECT `parser_runs`.* FROM `parser_runs` LEFT JOIN system_events ON parser_runs.id = system_events.parser_run_id WHERE `parser_runs`.`completed_at` IS NULL AND (system_events.created_at > '2017-08-07 10:09:03')
+----+-------------+---------------+--------+-------------------------   -------------+---------+---------+--------------------------------------+-    -------+-------------+
| id | select_type | table         | type   | possible_keys                          | key     | key_len | ref                                  | rows   |    Extra       |
+----+-------------+---------------+--------+--------------------------------------+---------+---------+--------------------------------------+--------+-------------+
|  1 | SIMPLE      | system_events | ALL    | index_system_events_on_parser_run_id | NULL    | NULL    | NULL                                    | 655946 | Using where |
|  1 | SIMPLE      | parser_runs   | eq_ref | PRIMARY                                | PRIMARY | 4       | ashblood.system_events.parser_run_id |      1 | Using where |
+----+-------------+---------------+--------+--------------------------------------+---------+---------+--------------------------------------+--------+-------------+

सेट में 2 पंक्तियाँ (0.00 सेकंड)

0
Suganya Selvarajan 7 अगस्त 2017, 10:33

3 जवाब

सबसे बढ़िया उत्तर

क्वेरी निष्पादन योजना में पहला चरण (EXPLAIN SELECT ... का आउटपुट) इंगित करता है कि संपूर्ण system_events तालिका को स्कैन किया जा रहा है ताकि यह जांचा जा सके कि system_events तालिका में कौन सी पंक्तियों का उपयोग किया जाएगा। join parser_runs टेबल के साथ।

कृपया, created_at कॉलम में system_events में एक इंडेक्स जोड़ें और क्वेरी दोहराएं। कृपया, यह सत्यापित करने के लिए नया निष्पादन पथ जांचें कि क्या संपूर्ण तालिका स्कैन की जा रही है, या यदि नई अनुक्रमणिका का उपयोग किया जा रहा है।

इसके अलावा, हालांकि शायद समस्या की जड़ नहीं है, आप तालिका parser_runs के type और completed_at कॉलम पर एक इंडेक्स जोड़ सकते हैं। कृपया, ध्यान दें कि मेरा मतलब प्रत्येक कॉलम पर एक इंडेक्स के बजाय दोनों कॉलम (दिए गए क्रम में) पर एक इंडेक्स है।

1
Bustikiller 7 अगस्त 2017, 14:37
INDEX(type, completed_at)
INDEX(completed_at, type)
INDEX(created_at, parser_run_id)
INDEX(parser_run_id, created_at)

यह स्पष्ट नहीं है कि अनुकूलक कौन से अनुक्रमणिका को पसंद करेगा; उन सभी को जोड़ें।

0
Rick James 16 अगस्त 2017, 00:13

जॉइन का प्रयोग न करें। इसके बजाय अलग-अलग प्रश्नों में शामिल प्रश्नों को तोड़ें और उन डेटा को चर में संग्रहीत करें। और बाद में उन डेटा से अपने वांछित परिणाम प्राप्त करें।

-1
Ketan Doshi 7 अगस्त 2017, 14:13