Ich habe keine Kontrolle über Dinge wie tmp_table_size
und max_heap_table_size
, und wenn unsere Tabellen wachsen, wächst die Zeit, die Abfragen benötigen, die temporäre Tabellen erfordern, geometrisch.
Ich frage mich, ob es eine Möglichkeit gibt, MySQL daran zu hindern, temporäre Tabellen für diese Abfragen zu verwenden. Was wäre der beste Ansatz in dieser Situation:
Hier ist ein Beispiel für den größten Täter:
SELECT `skills`.`id`
FROM (`jobs_skills`)
JOIN `jobs` ON (`jobs`.`id` = `jobs_skills`.`job_id`)
JOIN `skills` ON (`skills`.`id` = `jobs_skills`.`skill_id`)
WHERE `jobs`.`job_visibility_id` = 1
AND `jobs`.`active` = 1
AND `skills`.`valid` = 1
AND `jobs_skills`.`skill_id` IN (96,101,103,108,121,2610,99,119,2607,102,104,112,113,122,1032,1488,2608,109,126,1438,2310,2318,2622,118,1046,1387,2609,100,116,123,2611,2612,2616,2618,114,127,1562,1587,1608,2276,2615,125,1070,1071,1161,1658,2613,2614,2617,105,110,111,120,1394,1435)
GROUP BY `jobs_skills`.`job_id`
Dies copying to temp table
dauerte 107 Sekunden, 99% der gesamten Abfragezeit.
Trotz der Befürchtungen des Dr.-Syndroms biete ich an. . .
MEHR DETAILS
Hier ist die EXPLAIN
Anweisung für die Abfrage:
+----+-------------+-------------+--------+----------------------+--------------+---------+----------------------------------+--------+----------------------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------------+--------+----------------------+--------------+---------+----------------------------------+--------+----------------------------------------------+
| 1 | SIMPLE | jobs | ref | PRIMARY,active_index | active_index | 1 | const | 468958 | Using where; Using temporary; Using filesort |
| 1 | SIMPLE | jobs_skills | ref | PRIMARY | PRIMARY | 4 | 557574_prod.jobs.id | 1 | Using where; Using index |
| 1 | SIMPLE | skills | eq_ref | PRIMARY | PRIMARY | 4 | 557574_prod.jobs_skills.skill_id | 1 | Using where |
+----+-------------+-------------+--------+----------------------+--------------+---------+----------------------------------+--------+----------------------------------------------+
und hier sind die CREATE TABLE
Aussagen für die relevanten Tabellen:
| jobs | CREATE TABLE `jobs` (
`id` int(10) unsigned NOT NULL auto_increment,
`user_id` int(10) unsigned NOT NULL,
`title` varchar(40) NOT NULL,
`description` text NOT NULL,
`address_id` int(10) unsigned NOT NULL,
`proximity` smallint(3) unsigned NOT NULL default '15',
`job_payrate_id` tinyint(1) unsigned NOT NULL default '1',
`payrate` int(10) unsigned NOT NULL,
`start_date` int(10) unsigned NOT NULL,
`job_start_id` tinyint(1) unsigned NOT NULL default '1',
`duration` tinyint(1) unsigned NOT NULL COMMENT 'Full-time, Part-time, Flexible',
`posting_date` int(10) unsigned NOT NULL,
`revision_date` int(10) unsigned NOT NULL,
`expiration` int(10) unsigned NOT NULL,
`active` tinyint(1) unsigned NOT NULL default '1',
`team_size` tinyint(2) unsigned NOT NULL default '1',
`job_type_id` tinyint(1) unsigned NOT NULL default '1',
`job_shift_id` tinyint(1) unsigned NOT NULL default '1',
`job_visibility_id` tinyint(1) unsigned NOT NULL default '1',
`position_count` smallint(5) unsigned NOT NULL default '1',
`impressions` int(10) unsigned NOT NULL default '0',
`clicks` int(10) unsigned NOT NULL default '0',
`employer_email` varchar(100) NOT NULL default '',
`job_source_id` smallint(6) unsigned NOT NULL default '0',
`job_password` varchar(50) NOT NULL default '',
PRIMARY KEY (`id`),
KEY `active_index` (`active`),
KEY `user_id_index` (`user_id`),
KEY `address_id_index` (`address_id`),
KEY `posting_date_index` USING BTREE (`posting_date`)
) ENGINE=InnoDB AUTO_INCREMENT=875013 DEFAULT CHARSET=utf8
- -
| jobs_skills | CREATE TABLE `jobs_skills` (
`job_id` int(10) unsigned NOT NULL,
`skill_id` int(10) unsigned NOT NULL,
`required` tinyint(1) unsigned NOT NULL,
PRIMARY KEY (`job_id`,`skill_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 |
- -
| skills | CREATE TABLE `skills` (
`id` int(10) unsigned NOT NULL auto_increment,
`parent_id` int(10) unsigned NOT NULL,
`name` varchar(35) NOT NULL default '',
`description` varchar(250) NOT NULL,
`valid` tinyint(1) unsigned NOT NULL default '0',
`is_category` tinyint(1) unsigned NOT NULL default '0',
`last_edited` int(10) unsigned NOT NULL default '0',
`impressions` int(10) unsigned NOT NULL default '0',
`clicks` int(10) unsigned NOT NULL default '0',
`jobs` int(10) unsigned NOT NULL default '0',
PRIMARY KEY (`id`),
KEY `name` (`name`),
KEY `parent` (`parent_id`)
) ENGINE=InnoDB AUTO_INCREMENT=2657 DEFAULT CHARSET=utf8 |
Wie ich bereits sagte, ist dies nicht die einzige Abfrage mit diesem Problem. Daher wäre jeder allgemeine Rat am hilfreichsten, obwohl ich keinen für diese Abfrage spezifischen Rat ablehnen werde.