i have a problem with a left join. Tables are myisam.
Tables
CREATE TABLE `article` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`force_startpage` tinyint(1) DEFAULT '0',
`title` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
`text` longtext COLLATE utf8_unicode_ci,
`text_length` int(11) NOT NULL,
`created_at` datetime DEFAULT NULL,
PRIMARY KEY (`id`),
) ENGINE=MyISAM AUTO_INCREMENT=26767 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
CREATE TABLE `article_category` (
`article_id` bigint(20) NOT NULL DEFAULT '0',
`category_id` bigint(20) NOT NULL DEFAULT '0',
`rank` bigint(20) DEFAULT '0',
PRIMARY KEY (`article_id`,`category_id`),
KEY `category_id` (`category_id`),
KEY `article_id` (`article_id`),
KEY `category_id_2` (`category_id`),
KEY `article_id_2` (`article_id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
CREATE TABLE `category` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`name` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
`slug` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
`created_at` datetime DEFAULT NULL,
`updated_at` datetime DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=6 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
CREATE TABLE `article_image` (
`article_id` bigint(20) NOT NULL DEFAULT '0',
`image_id` bigint(20) NOT NULL DEFAULT '0',
`rank` bigint(20) DEFAULT NULL,
PRIMARY KEY (`article_id`,`image_id`),
KEY `image_id` (`image_id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
CREATE TABLE `image` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`bu` varchar(400) COLLATE utf8_unicode_ci DEFAULT NULL,
`copyright` varchar(400) COLLATE utf8_unicode_ci DEFAULT NULL,
`mimetype` varchar(4) COLLATE utf8_unicode_ci DEFAULT 'jpg',
`width` int(11) DEFAULT NULL,
`height` int(11) DEFAULT NULL,
`created_at` datetime DEFAULT NULL,
`updated_at` datetime DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=71644 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
ALTER TABLE article_image ADD FOREIGN KEY (image_id) REFERENCES image(id) ON DELETE CASCADE;
ALTER TABLE article_image ADD FOREIGN KEY (article_id) REFERENCES article(id) ON DELETE CASCADE;
ALTER TABLE article_category ADD FOREIGN KEY (category_id) REFERENCES category(id) ON DELETE CASCADE;
ALTER TABLE article_category ADD FOREIGN KEY (article_id) REFERENCES article(id) ON DELETE CASCADE;
My Query 1 Takes 0.05 ms:
SELECT
DISTINCT id,
force_startpage,
created_at
FROM
(
SELECT
a.id AS id,
a.force_startpage,
a.start_date,
a.title,
a.text_length,
a.created_at
FROM
article a
LEFT JOIN article_category ac ON a.id = ac.article_id
LEFT JOIN category c ON c.id = ac.category_id
LEFT JOIN article_image ai ON a.id = ai.article_id
LEFT JOIN image i ON i.id = ai.image_id
WHERE
a.text_length > 1
AND c.id = 1
ORDER BY
a.force_startpage DESC,
a.created_at DESC
) dctrn_result
ORDER BY
force_startpage DESC,
created_at DESC
LIMIT
5
And the same Query with selecting the text field from article takes 15 Seconds
SELECT
DISTINCT id,
force_startpage,
created_at
FROM
(
SELECT
a.id AS id,
a.force_startpage,
a.start_date,
a.title,
a.text
a.text_length,
a.created_at
FROM
article a
LEFT JOIN article_category ac ON a.id = ac.article_id
LEFT JOIN category c ON c.id = ac.category_id
LEFT JOIN article_image ai ON a.id = ai.article_id
LEFT JOIN image i ON i.id = ai.image_id
WHERE
a.text_length > 1
AND c.id = 1
ORDER BY
a.force_startpage DESC,
a.created_at DESC
) dctrn_result
ORDER BY
force_startpage DESC,
created_at DESC
LIMIT
5
Table Article has ~20,000 rows
Table Category has 5 rows
Table Image has ~ 120,000 rows
I don't understand this huge time difference. If anyone could explain the problem and even better give hints for a fix?
Edit/ Explain results:
Query 1:
+----+-------------+------------+--------+-----------------------------------------------------------+---------------+---------+------------------------+-------+----------------------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+------------+--------+-----------------------------------------------------------+---------------+---------+------------------------+-------+----------------------------------------------+
| 1 | PRIMARY | <derived2> | ALL | NULL | NULL | NULL | NULL | 38504 | Using temporary; Using filesort |
| 2 | DERIVED | c | const | PRIMARY | PRIMARY | 8 | | 1 | Using index; Using temporary; Using filesort |
| 2 | DERIVED | ac | ref | PRIMARY,category_id,article_id,category_id_2,article_id_2 | category_id_2 | 8 | | 9239 | Using where |
| 2 | DERIVED | a | eq_ref | PRIMARY | PRIMARY | 8 | kinozeit.ac.article_id | 1 | Using where |
| 2 | DERIVED | ai | ref | PRIMARY | PRIMARY | 8 | kinozeit.a.id | 4 | Using index |
| 2 | DERIVED | i | eq_ref | PRIMARY | PRIMARY | 8 | kinozeit.ai.image_id | 1 | Using index |
+----+-------------+------------+--------+-----------------------------------------------------------+---------------+---------+------------------------+-------+----------------------------------------------+
6 rows in set (0.31 sec)
Query 2:
+----+-------------+------------+--------+-----------------------------------------------------------+---------------+---------+------------------------+-------+----------------------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+------------+--------+-----------------------------------------------------------+---------------+---------+------------------------+-------+----------------------------------------------+
| 1 | PRIMARY | <derived2> | ALL | NULL | NULL | NULL | NULL | 38504 | Using temporary; Using filesort |
| 2 | DERIVED | c | const | PRIMARY | PRIMARY | 8 | | 1 | Using index; Using temporary; Using filesort |
| 2 | DERIVED | ac | ref | PRIMARY,category_id,article_id,category_id_2,article_id_2 | category_id_2 | 8 | | 9239 | Using where |
| 2 | DERIVED | a | eq_ref | PRIMARY | PRIMARY | 8 | kinozeit.ac.article_id | 1 | Using where |
| 2 | DERIVED | ai | ref | PRIMARY | PRIMARY | 8 | kinozeit.a.id | 4 | Using index |
| 2 | DERIVED | i | eq_ref | PRIMARY | PRIMARY | 8 | kinozeit.ai.image_id | 1 | Using index |
+----+-------------+------------+--------+-----------------------------------------------------------+---------------+---------+------------------------+-------+----------------------------------------------+
6 rows in set (12.20 sec)
Edit 2 / Show Profiles (Due to comment from tombom)
+--------------------------------+----------+
| Status | Duration |
+--------------------------------+----------+
| starting | 0.000019 |
| Waiting for query cache lock | 0.000005 |
| checking query cache for query | 0.000129 |
| checking permissions | 0.000007 |
| checking permissions | 0.000004 |
| checking permissions | 0.000004 |
| checking permissions | 0.000004 |
| checking permissions | 0.000006 |
| Opening tables | 0.000036 |
| System lock | 0.000373 |
| optimizing | 0.000030 |
| statistics | 0.000095 |
| preparing | 0.000034 |
| Creating tmp table | 0.000230 |
| executing | 0.000006 |
| Copying to tmp table | 0.298139 |
| Sorting result | 0.049349 |
| Sending data | 0.281068 |
| removing tmp table | 1.380771 |
| Sending data | 0.000013 |
| Waiting for query cache lock | 0.000003 |
| Sending data | 0.000019 |
| init | 0.000017 |
| optimizing | 0.000004 |
| statistics | 0.000007 |
| preparing | 0.000007 |
| Creating tmp table | 0.000022 |
| executing | 0.000002 |
| Copying to tmp table | 0.065963 |
| Sorting result | 0.000718 |
| Sending data | 0.000015 |
| end | 0.000002 |
| removing tmp table | 0.000005 |
| end | 0.000003 |
| query end | 0.000002 |
| closing tables | 0.000002 |
| removing tmp table | 0.205378 |
| closing tables | 0.000018 |
| freeing items | 0.000012 |
| Waiting for query cache lock | 0.000014 |
| freeing items | 0.000012 |
| Waiting for query cache lock | 0.000002 |
| freeing items | 0.000001 |
| storing result in query cache | 0.000002 |
| logging slow query | 0.000002 |
| cleaning up | 0.000003 |
+--------------------------------+----------+
I'ts a bit faster now, because of query cache and -repair tables. But problem still exists.
EXPLAIN
in front of your queries and post the results.SQL_NO_CACHE
to avoid query cache interferences.