I have the following query:
select
`stories`.*
from
`stories`
inner join `communities` on `stories`.`community_id` = `communities`.`id`
inner join `communities_followers` on `communities`.`id` = `communities_followers`.`community_id`
where
`is_published` = 1
and `communities_followers`.`user_id` = 1
and `communities_followers`.`status` = 1
order by
`stories`.`created_at` desc
limit
20 offset 0
With an single index on communities_followers.user_id and a compound index on ['user_id', 'status']
When doing an explain on the query, this is the result:
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+-----------------------+------------+--------+--------------------------------------------------------------------------------------------------------------------------------------+-------------------------------------+---------+---------------------------------------------+------+----------+----------------------------------------------+
| 1 | SIMPLE | communities_followers | NULL | ref | communities_followers_user_id_index,communities_followers_community_id_index,communities_followers_community_id_user_id_status_index | communities_followers_user_id_index | 4 | const | 77 | 10.00 | Using where; Using temporary; Using filesort |
| 1 | SIMPLE | communities | NULL | eq_ref | PRIMARY,communities_id_default_community_index | PRIMARY | 4 | grepless.communities_followers.community_id | 1 | 100.00 | Using index |
| 1 | SIMPLE | stories | NULL | ref | stories_community_id_index | stories_community_id_index | 4 | grepless.communities_followers.community_id | 3968 | 100.00 | NULL |
+----+-------------+-----------------------+------------+--------+--------------------------------------------------------------------------------------------------------------------------------------+-------------------------------------+---------+---------------------------------------------+------+----------+----------------------------------------------+
Explain
What else can I do to improve this? communities_followers does contain a ton of records.
Stories table:
CREATE TABLE `stories` (
`id` int unsigned NOT NULL AUTO_INCREMENT,
`user_id` int unsigned NOT NULL,
`publisher_id` int unsigned DEFAULT NULL,
`community_id` int unsigned NOT NULL,
`content_type_id` int unsigned NOT NULL DEFAULT '10',
`title` varchar(1000) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL,
`description` mediumtext CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci,
`meta_description` mediumtext CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci,
`score` int NOT NULL DEFAULT '0',
`score_alternate` int NOT NULL DEFAULT '0',
`views` int NOT NULL DEFAULT '0',
`url` varchar(1000) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`source_url` text CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci,
`picture` varchar(191) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`meta` text CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci,
`embed` text CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci,
`picture_original` varchar(191) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`picture_huge` varchar(191) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`picture_big` varchar(191) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`picture_small` varchar(191) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`picture_extra` varchar(191) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`slug` varchar(191) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`is_published` tinyint(1) NOT NULL DEFAULT '1',
`is_summarized` tinyint(1) NOT NULL DEFAULT '0',
`language` varchar(8) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`show_in_feed` tinyint(1) NOT NULL DEFAULT '1',
`is_pinned` tinyint(1) NOT NULL DEFAULT '0',
`has_pictures_localized` tinyint(1) NOT NULL DEFAULT '0',
`has_pictures_optimized` tinyint(1) NOT NULL DEFAULT '0',
`has_audio` tinyint(1) NOT NULL DEFAULT '0',
`created_at` timestamp NULL DEFAULT NULL,
`updated_at` timestamp NULL DEFAULT NULL,
`deleted_at` timestamp NULL DEFAULT NULL,
`author` varchar(191) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`comments_count` bigint NOT NULL DEFAULT '0',
PRIMARY KEY (`id`),
KEY `stories_created_at_index` (`created_at`),
KEY `stories_user_id_index` (`user_id`),
KEY `stories_community_id_index` (`community_id`),
KEY `stories_content_type_id_index` (`content_type_id`),
KEY `stories_score_index` (`score`),
KEY `stories_slug_index` (`slug`),
KEY `stories_show_in_feed_index` (`show_in_feed`),
KEY `stories_publisher_id_index` (`id`),
KEY `stories_deleted_at_is_published_content_type_id_index` (`deleted_at`,`is_published`,`content_type_id`),
KEY `stories_publisher_id_deleted_at_index` (`publisher_id`,`deleted_at`),
KEY `stories_is_published_deleted_at_index` (`is_published`,`deleted_at`,`community_id`) USING BTREE
) ENGINE=MyISAM AUTO_INCREMENT=952978 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
communities table
communities | CREATE TABLE `communities` (
`id` int unsigned NOT NULL AUTO_INCREMENT,
`user_id` int unsigned DEFAULT NULL,
`name` varchar(60) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL,
`description` text CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci,
`slug` varchar(191) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`header` varchar(191) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`color` varchar(191) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`background` varchar(191) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`background_cover` tinyint(1) NOT NULL DEFAULT '1',
`picture_big` varchar(191) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`picture_small` varchar(191) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`has_pictures_optimized` tinyint(1) NOT NULL DEFAULT '0',
`default_community` tinyint(1) NOT NULL DEFAULT '0',
`is_popular` tinyint(1) NOT NULL DEFAULT '0',
`status` smallint NOT NULL DEFAULT '1',
`created_at` timestamp NULL DEFAULT NULL,
`updated_at` timestamp NULL DEFAULT NULL,
`stories_count` bigint NOT NULL DEFAULT '0',
PRIMARY KEY (`id`),
KEY `communities_user_id_index` (`user_id`),
KEY `communities_name_index` (`name`),
KEY `communities_slug_index` (`slug`),
KEY `communities_status_index` (`status`),
KEY `communities_default_community_index` (`default_community`),
KEY `communities_id_default_community_index` (`id`,`default_community`)
) ENGINE=MyISAM AUTO_INCREMENT=183 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci |
Communities followers table
communities_followers | CREATE TABLE `communities_followers` (
`id` int unsigned NOT NULL AUTO_INCREMENT,
`user_id` int unsigned NOT NULL,
`community_id` int unsigned NOT NULL,
`status` smallint NOT NULL DEFAULT '0',
`created_at` timestamp NULL DEFAULT NULL,
`updated_at` timestamp NULL DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `communities_followers_user_id_index` (`user_id`),
KEY `communities_followers_community_id_index` (`community_id`),
KEY `communities_followers_community_id_user_id_status_index` (`community_id`,`user_id`,`status`)
) ENGINE=MyISAM AUTO_INCREMENT=326484 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci |
SELECT
`stories`.*
FROM
`communities_followers`
INNER JOIN
`stories`
ON `stories`. `community_id` = `communities_followers`.`community_id`
WHERE
`communities_followers`.`user_id` = 1
AND `communities_followers`.`status` = 1
AND `stories`.`is_published` = 1
ORDER BY
`stories`.`created_at` DESC
LIMIT
20 OFFSET 0
Then to speed up the initial filter index...
communities_followers(user_id, status, community_id)
Then to speed up the join AND the ordering and limit...
stories(community_id, is_published, created_at)
OR
stories(is_published, created_at, community_id)
But I'd use EXISTS, as it will still work if you query against multiple users (without causing duplication in the results)...
SELECT
`stories`.*
FROM
`stories`
WHERE
`stories`.`is_published` = 1
AND EXISTS (
SELECT *
FROM `communities_followers`
WHERE `communities_followers`.`user_id` = 1
AND `communities_followers`.`status` = 1
AND `communities_followers`.`community_id` = `stories`.`community_id`
)
ORDER BY
`stories`.`created_at` DESC
LIMIT
20 OFFSET 0
Related
Here is my table:
CREATE TABLE `cerp_oms_order` (
`id` bigint NOT NULL,
`company_id` bigint NOT NULL,
`order_no` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
`source_type` int NOT NULL,
`shop_id` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
`outer_shop` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
`origin_status` int NOT NULL,
`system_status` int NOT NULL,
`created_time` datetime DEFAULT NULL,
`paid_time` datetime DEFAULT NULL,
`sent_time` datetime DEFAULT NULL,
`end_time` datetime DEFAULT NULL,
`modify_time` datetime DEFAULT NULL,
`delivery_deadline_time` datetime DEFAULT NULL,
`amount` text CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL ,
`spu_kind` int NOT NULL,
`sku_kind` int NOT NULL,
`total_quantity` decimal(16,4) NOT NULL,
`buyer_id` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
`outer_buyer_identifier` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '',
`tax_info` varchar(256) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL,
`warehouse_owner` int DEFAULT NULL,
`warehouse_id` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL,
`logistics_type` int NOT NULL,
`logistics_outer_info` varchar(256) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL,
`delivery_id` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL,
`delivery_no` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL,
`wave_no` varchar(64) DEFAULT '',
`is_deleted` tinyint NOT NULL DEFAULT '0',
`backend_processing_type` tinyint NOT NULL,
`create_type` tinyint NOT NULL,
`is_hang_up` tinyint NOT NULL,
`hang_up_case_type` smallint DEFAULT NULL,
`hang_up_case_id` bigint DEFAULT NULL,
`rc_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
`rm_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`vat` varchar(128) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL,
`weight` decimal(16,4) NOT NULL DEFAULT '0.0000',
`volume` decimal(16,4) NOT NULL DEFAULT '0.0000',
`is_abnormal` tinyint NOT NULL DEFAULT '0',
`estimate_profit` decimal(16,4) NOT NULL DEFAULT '0.0000',
`business_man_id` varchar(256) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL,
`business_man` varchar(256) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL,
`currency` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL,
`net_amount_summary` decimal(19,4) NOT NULL,
`domestic_amount` decimal(19,4) NOT NULL,
`secret_key` varchar(64) DEFAULT '',
`secretKey` varchar(255) DEFAULT NULL,
`sale_id` bigint DEFAULT NULL,
`total_refund_include_tax` decimal(16,4) NOT NULL DEFAULT '0.0000',
`total_refund_money` decimal(16,4) NOT NULL DEFAULT '0.0000',
`total_refund_tax` decimal(16,4) NOT NULL DEFAULT '0.0000',
`total_return_goods` decimal(16,2) NOT NULL DEFAULT '0.00',
PRIMARY KEY (`id`),
UNIQUE KEY `key_order_no` (`order_no`),
KEY `idx_order_company_id` (`company_id`,`created_time`),
KEY `IDX_RM_TIME` (`rm_time`),
KEY `IDX_IS_ABNORMAL` (`is_abnormal`),
KEY `cerp_oms_order_company_id_index` (`company_id`),
KEY `idx_order_company_status_deleted` (`company_id`,`is_deleted`,`system_status`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='system order table'
explain select *
from cerp_oms_order
inner join (select id
from cerp_oms_order
where source_type = 43
order by created_time) as tmp using (id);
id
select_type
table
partitions
type
possible_keys
key
key_len
ref
rows
filtered
Extra
1
SIMPLE
cerp_oms_order
null
ALL
PRIMARY
null
null
null
60787
10
Using where
1
SIMPLE
cerp_oms_order
null
eq_ref
PRIMARY
PRIMARY
8
cerp_oms_1.cerp_oms_order.id
1
100
null
using inner join execution: 7 ms, fetching: 109 ms
VS
explain
select *
from cerp_oms_order
where source_type = 43
order by created_time;
id
select_type
table
partitions
type
possible_keys
key
key_len
ref
rows
filtered
Extra
1
SIMPLE
cerp_oms_order
null
ALL
null
null
null
null
60787
10
Using where; Using filesort
using simple where clause execution: 80 ms, fetching: 138 ms
I don't understand why use inner join can speed up my sql?
If you had
INDEX(source_type, created_time)
both formulations would run faster. And, I think, the second would be faster.
As for "why". Look at what the second does:
Scan the entire table ("table scan") looking for rows with source_type = 43.
For each matching row, gather all the columns (*) from the row, into a temp table.
Sort that temp table. Note that this is bulkier than with the subquery that hauls around only id.
Deliver the results.
With the INDEX I suggest:
Look in the index's B+Tree for all 'rows' with source_type = 43.
Since those rows are sorted by created_time, not "sort" pass will be needed now or later.
Each of those index rows will contain id. (That's the way InnoDB gets to the rest of the columns), so
Look up the desired rows in the data's B+Tree and pull out all (*) the columns.
Deliver them.
Note that the JOIN version works essentially the same, but, technically speaking, the ORDER BY may get lost. If it does get lost, you would need to add a second ORDER BY, thereby forcing a sort.
(Unrelated) Your "KEY cerp_oms_order_company_id_index (company_id)," can be dropped since there are two other indexes starting with company_id.
More on optimizing indexes: Index Cookbook
have a small blog site, host provider runs Server version: 5.5.5-10.3.34-MariaDB-cll-lve MariaDB Server. The last weeks i noticed fetching the posts is slower, and it turns out the query now takes 6 seconds.
the in question query:
SELECT * FROM POSTS
JOIN POST_CATEGORIES on POST_CATEGORIES.CATEG_ID = POSTS.POST_CATEGORY
LEFT JOIN USERS on POSTS.POST_USERNAME = USERS.USER_USERNAME
WHERE POST_STATUS = 'ENA'
AND POST_IS_PUBLIC = 'Y'
ORDER BY POST_IS_STICKY DESC, (TIMESTAMPDIFF(SECOND, POST_CREATION_DATE, now())-(POST_LIKES-POST_DISLIKES)*3600) ASC
LIMIT 0, 12;
if i remove the order by the query time drops to 0.04 sec, but obviously it is needed for proper sorting. Same effect happens if i remove the left join to USERS, but i would like to focus on the order by clause.
Table rows:
POSTS: 62K
POST_CATEGORIES: 20
USERS: 180
Interesting finding:
There are already indexes (primary/unique/foreign key) on the tables, but not on the columns involved, for the simplicity i am not adding them here.
But i did try adding the index:
INDEX `POSTS_OPTIMIZING_INDEX` (`POST_CREATION_DATE`, `POST_LIKES`, `POST_DISLIKES`) USING BTREE,
and FORCE INDEX (POSTS_OPTIMIZING_INDEX) and saw something interesting:
on the MariaDB, literally no difference.
on mysql community server Server version: 5.7.20 MySQL Community Server (GPL) that i have home, the query duration from 6 seconds went down to 0.12sec, which is definitely acceptable.
Any suggestions on optimizing the SQL, or tuning mariadb?
EDIT
the table definitions:
POSTS:
CREATE TABLE `POSTS` (
`POST_ID` int(11) NOT NULL AUTO_INCREMENT,
`POST_URL_ID` varchar(30) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`POST_TYPE` varchar(3) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`POST_CATEGORY` int(3) DEFAULT NULL,
`POST_IS_PUBLIC` varchar(1) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`POST_IS_STICKY` varchar(1) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`POST_FREE_TEXT` varchar(5000) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`POST_IMAGE_FILE` varchar(1000) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`POST_VIDEO_URL` varchar(100) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`POST_IS_FROM_USER` varchar(1) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`POST_USERNAME` varchar(20) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`POST_CREATION_DATE` timestamp NOT NULL DEFAULT current_timestamp(),
`POST_STATUS` varchar(3) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT 'ENA',
`POST_LIKES` int(5) DEFAULT 0,
`POST_DISLIKES` int(5) DEFAULT 0,
`POST_ADDITIONAL_INFO` varchar(10) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`POST_FB_OBJ_ID` varchar(50) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`POST_FB_OBJ_TYPE` varchar(10) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`POST_FB_IMG_LAST_CHECKED` timestamp NULL DEFAULT NULL,
`POST_FB_IMG_LAST_CHECK_RESULT` varchar(3) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`POST_TWITTER_OBJ_ID` varchar(50) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
PRIMARY KEY (`POST_ID`),
UNIQUE KEY `POST_URL_ID` (`POST_URL_ID`),
KEY `FK_POSTS_POST_CATEGORIES` (`POST_CATEGORY`),
CONSTRAINT `FK_POSTS_POST_CATEGORIES` FOREIGN KEY (`POST_CATEGORY`) REFERENCES `POST_CATEGORIES` (`CATEG_ID`)
) ENGINE=InnoDB AUTO_INCREMENT=62529 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
POST_CATEGORIES:
CREATE TABLE `POST_CATEGORIES` (
`CATEG_ID` int(11) NOT NULL AUTO_INCREMENT,
`CATEG_URL_NAME` varchar(50) COLLATE utf8_unicode_ci DEFAULT NULL,
`CATEG_NAME` varchar(50) COLLATE utf8_unicode_ci DEFAULT NULL,
PRIMARY KEY (`CATEG_ID`)
) ENGINE=InnoDB AUTO_INCREMENT=51 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci
USERS:
CREATE TABLE `USERS` (
`USER_ID` int(11) NOT NULL AUTO_INCREMENT,
`USER_MAIL_ADDRESS` varchar(100) COLLATE utf8_unicode_ci DEFAULT NULL,
`USER_USERNAME` varchar(20) COLLATE utf8_unicode_ci DEFAULT NULL,
`USER_PASSWORD` varchar(60) COLLATE utf8_unicode_ci DEFAULT NULL,
`USER_CREATION_DATE` timestamp NULL DEFAULT current_timestamp(),
`USER_LAST_LOGIN_DATE` timestamp NULL DEFAULT NULL,
`USER_FROM_FB` varchar(1) COLLATE utf8_unicode_ci DEFAULT NULL,
`USER_FB_MAIL_ADDRESS` varchar(100) COLLATE utf8_unicode_ci DEFAULT NULL,
`USER_FB_FULL_NAME` varchar(100) COLLATE utf8_unicode_ci DEFAULT NULL,
`USER_SPECIAL` varchar(1) COLLATE utf8_unicode_ci DEFAULT NULL,
`USER_ACCT_STATUS` varchar(3) COLLATE utf8_unicode_ci DEFAULT 'ENA',
`USER_POSTS_COUNT` int(5) DEFAULT 0,
`USER_NAME` varchar(100) COLLATE utf8_unicode_ci DEFAULT NULL,
`USER_QUOTE` varchar(200) COLLATE utf8_unicode_ci DEFAULT NULL,
`USER_ABOUT_MYSELF` varchar(500) COLLATE utf8_unicode_ci DEFAULT NULL,
`USER_WEBSITE` varchar(100) COLLATE utf8_unicode_ci DEFAULT NULL,
`USER_FB` varchar(150) COLLATE utf8_unicode_ci DEFAULT NULL,
`USER_TWITTER` varchar(100) COLLATE utf8_unicode_ci DEFAULT NULL,
`USER_LOCATION` varchar(150) COLLATE utf8_unicode_ci DEFAULT NULL,
`USER_BIRTHDAY` varchar(10) COLLATE utf8_unicode_ci DEFAULT NULL,
`USER_PROFILE_PIC` varchar(20) COLLATE utf8_unicode_ci DEFAULT NULL,
`USER_PROFILE_PIC_FROM_FB` varchar(1) COLLATE utf8_unicode_ci DEFAULT NULL,
PRIMARY KEY (`USER_ID`),
UNIQUE KEY `USER_USERNAME` (`USER_USERNAME`)
) ENGINE=InnoDB AUTO_INCREMENT=188 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci
the EXPLAIN:
mysql> EXPLAIN
-> SELECT * FROM POSTS
-> JOIN POST_CATEGORIES on POST_CATEGORIES.CATEG_ID = POSTS.POST_CATEGORY
-> LEFT JOIN USERS on POSTS.POST_USERNAME = USERS.USER_USERNAME
-> WHERE POST_STATUS = 'ENA'
-> AND POST_IS_PUBLIC = 'Y'
-> ORDER BY POST_IS_STICKY DESC, (TIMESTAMPDIFF(SECOND, POST_CREATION_DATE, now())-(POST_LIKES-POST_DISLIKES)*3600) ASC
-> LIMIT 0, 12;
+------+-------------+-----------------+--------+--------------------------+---------+---------+--------------------------------+-------+-------------------------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+------+-------------+-----------------+--------+--------------------------+---------+---------+--------------------------------+-------+-------------------------------------------------+
| 1 | SIMPLE | POSTS | ALL | FK_POSTS_POST_CATEGORIES | NULL | NULL | NULL | 61407 | Using where; Using temporary; Using filesort |
| 1 | SIMPLE | POST_CATEGORIES | eq_ref | PRIMARY | PRIMARY | 4 | MY_DB.POSTS.POST_CATEGORY | 1 | |
| 1 | SIMPLE | USERS | ALL | NULL | NULL | NULL | NULL | 178 | Using where; Using join buffer (flat, BNL join) |
+------+-------------+-----------------+--------+--------------------------+---------+---------+--------------------------------+-------+-------------------------------------------------+
3 rows in set (0.03 sec)
mysql>
and removing the 2 joins:
mysql> EXPLAIN
-> SELECT * FROM POSTS
-> WHERE POST_STATUS = 'ENA'
-> AND POST_IS_PUBLIC = 'Y'
-> ORDER BY POST_IS_STICKY DESC, (TIMESTAMPDIFF(SECOND, POST_CREATION_DATE, now())-(POST_LIKES-POST_DISLIKES)*3600) ASC
-> LIMIT 0, 12;
+------+-------------+-------+------+---------------+------+---------+------+-------+-----------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+------+-------------+-------+------+---------------+------+---------+------+-------+-----------------------------+
| 1 | SIMPLE | POSTS | ALL | NULL | NULL | NULL | NULL | 61407 | Using where; Using filesort |
+------+-------------+-------+------+---------------+------+---------+------+-------+-----------------------------+
1 row in set (0.02 sec)
mysql>
TIA
"Explode-implode" syndrome. Rewrite the query to get the 12 rows first, then JOIN to the other tables.
SELECT ...
FROM ( SELECT user_id,
is_sticky,
(TIMESTAMPDIFF(SECOND, POST_CREATION_DATE, now()) -
(POST_LIKES-POST_DISLIKES)*3600) AS metric
FROM POSTS
WHERE POST_STATUS = 'ENA'
AND POST_IS_PUBLIC = 'Y'
ORDER BY
POST_IS_STICKY DESC, metric ASC
LIMIT 0, 12
) AS x
JOIN POSTS AS p USING(user_id)
JOIN POST_CATEGORIES AS pc ON pc.CATEG_ID = p.POST_CATEGORY
LEFT JOIN USERS AS u ON p.POST_USERNAME = u.USER_USERNAME
ORDER BY x.POST_IS_STICKY DESC, x.metric ASC
Replace the elipsis with the columns you really need.
Yes, POSTS is looked into a second time, but only for 12 rows, and by the PK. Similarly, the other rows are reached into only 12 times.
Yes, the ORDER BY needs to be repeated. The LIMIT may need repeating if the JOIN creates extra rows (eg, multiple categories).
Consider using
SELECT ...
( SELECT GROUP_CONCAT(CATEG_NAME) FROM POST_CATEGORIES
WHERE categ_id = p.post_categories ) AS Categories,
...
instead of JOINing to POST_CATEGORIES, especially if there are multiple categories.
This may help with performance, but only if it is selective enough:
INDEX(post_tatus, post_is_public)
Table Structures:
CREATE TABLE `ebay_items` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`item_id` bigint(20) NOT NULL,
`item_url` text COLLATE utf8mb4_unicode_ci NOT NULL,
`title` text COLLATE utf8mb4_unicode_ci NOT NULL,
`main_image_low` text COLLATE utf8mb4_unicode_ci NOT NULL,
`main_image_mid` text COLLATE utf8mb4_unicode_ci NOT NULL,
`main_image_max` text COLLATE utf8mb4_unicode_ci NOT NULL,
`price` decimal(10,2) NOT NULL,
`price_with_sign` varchar(191) COLLATE utf8mb4_unicode_ci NOT NULL,
`shipping_price` decimal(10,2) NOT NULL,
`shipping_with_sign` varchar(191) COLLATE utf8mb4_unicode_ci NOT NULL,
`quantity` int(11) NOT NULL,
`brand` varchar(191) COLLATE utf8mb4_unicode_ci NOT NULL,
`model` varchar(191) COLLATE utf8mb4_unicode_ci NOT NULL,
`upc` varchar(191) COLLATE utf8mb4_unicode_ci NOT NULL,
`variation_array` longtext COLLATE utf8mb4_unicode_ci NOT NULL,
`image_array` longtext COLLATE utf8mb4_unicode_ci NOT NULL,
`category_array` longtext COLLATE utf8mb4_unicode_ci NOT NULL,
`step_number` int(11) NOT NULL,
`archived` int(11) NOT NULL,
`archived_number` int(11) NOT NULL,
`user_id` int(11) NOT NULL,
`created_at` timestamp NULL DEFAULT NULL,
`updated_at` timestamp NULL DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=5765 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
CREATE TABLE `amazon_items` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`asin` varchar(191) COLLATE utf8mb4_unicode_ci NOT NULL,
`related_ebay_item_id` bigint(20) NOT NULL,
`item_url` text COLLATE utf8mb4_unicode_ci NOT NULL,
`title` text COLLATE utf8mb4_unicode_ci NOT NULL,
`main_image_low` text COLLATE utf8mb4_unicode_ci NOT NULL,
`main_image_mid` text COLLATE utf8mb4_unicode_ci NOT NULL,
`main_image_max` text COLLATE utf8mb4_unicode_ci NOT NULL,
`buy_box_price` decimal(10,2) NOT NULL,
`buy_box_price_with_sign` text COLLATE utf8mb4_unicode_ci NOT NULL,
`lowest_other_sellers_price` longtext COLLATE utf8mb4_unicode_ci NOT NULL,
`other_number_of_seller` varchar(191) COLLATE utf8mb4_unicode_ci NOT NULL,
`variation_array` longtext COLLATE utf8mb4_unicode_ci NOT NULL,
`category_array` longtext COLLATE utf8mb4_unicode_ci NOT NULL,
`step_number` int(11) NOT NULL,
`archived` int(11) NOT NULL,
`archived_number` int(11) NOT NULL,
`status` int(11) NOT NULL DEFAULT '0',
`user_id` int(11) NOT NULL,
`created_at` timestamp NULL DEFAULT NULL,
`updated_at` timestamp NULL DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=7398 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
Create Table
CREATE TABLE `item_attributes` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`amazon_id` bigint(20) NOT NULL,
`sku` varchar(191) COLLATE utf8mb4_unicode_ci NOT NULL,
`quantity` varchar(191) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`currency` varchar(191) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`list_price` decimal(10,2) DEFAULT NULL,
`min_price` decimal(10,2) DEFAULT NULL,
`max_price` decimal(10,2) DEFAULT NULL,
`estimated_profit` decimal(10,2) DEFAULT NULL,
`added_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
`refresh_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
`user_id` int(11) NOT NULL,
`status` smallint(6) NOT NULL,
`created_at` timestamp NULL DEFAULT NULL,
`updated_at` timestamp NULL DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=6000 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
CREATE TABLE `import_items_logs` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`ebay_id` int(11) NOT NULL,
`amazon_id` int(11) NOT NULL,
`tag` varchar(191) COLLATE utf8mb4_unicode_ci NOT NULL,
`status` int(11) NOT NULL,
`user_id` int(11) NOT NULL,
`created_at` timestamp NULL DEFAULT NULL,
`updated_at` timestamp NULL DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=6002 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
SELECT ei.id
, ei.item_id
, ei.item_url
, ei.title
, ei.main_image_low
, ei.price
, ei.price_with_sign
, ei.shipping_price
, ei.shipping_with_sign
, ei.quantity
, ei.brand
, ei.model
, ei.upc
, ei.step_number
, ei.archived
, ei.archived_number
, ei.user_id
, ei.created_at
, ei.updated_at
, ai.id amazon_id
, ai.asin
, ai.item_url amazon_item_url
, ai.title amazon_title
, ai.main_image_low amazon_low_image
, ai.buy_box_price_with_sign
, ai.lowest_other_sellers_price
, ai.other_number_of_seller
, ai.category_array
, ai.status amazon_status
, ia.sku
, ia.list_price
, ia.min_price
, ia.max_price
, ia.estimated_profit
, ia.status attr_status
, ia.added_time attr_added_time
, ia.refresh_time attr_refresh_time
, l.status import_status
, l.tag import_tag
FROM ebay_items ei
JOIN amazon_items ai
ON ai.related_ebay_item_id = ei.id
LEFT
JOIN item_attributes ia
ON ia.amazon_id = ai.id
LEFT
JOIN import_items_logs l
ON l.ebay_id = ei.id
WHERE ei.user_id = 1
AND ei.archived =2
GROUP
BY ei.id
I'm trying to get item and additional details and Those are in separated tables
There are 4 tables
ebay_items, amazon_items, item_attributes, import_items_logs
This what i want as result,
ebay_items and amazon_items must be matched (ebay_items.id =
amazon_items.related_ebay_item_id)
also item_attributes (amazon_items.id = item_attributes.amazon_id)
and import_items_logs (ebay_items.id = import_items_logs.ebay_id)
records need if any records exist
This is my query when i ran on local it's takes 50+sec or amazon server it's take 12sec to finish. What's wrong im doing here. Total records is 2600. i don't know why it's too slow
Query Explain
id select_type table type possible_keys key key_len ref rows Extra
------ ----------- ------ ------ ------------- ------- ------- --------------------------------------- ------ --------------------------------------------------------
1 SIMPLE ai ALL (NULL) (NULL) (NULL) (NULL) 4277 Using temporary; Using filesort
1 SIMPLE ei eq_ref PRIMARY PRIMARY 8 other_rp-tool-2.ai.related_ebay_item_id 1 Using where
1 SIMPLE ia ALL (NULL) (NULL) (NULL) (NULL) 3134 Using where; Using join buffer (flat, BNL join)
1 SIMPLE l ALL (NULL) (NULL) (NULL) (NULL) 6076 Using where; Using join buffer (incremental, BNL join) ```
we are getting frequent slow log alerts because of below query.this query using indexes
i was tried to optimize this query but no luck support me to optimize slow query and how to improve the performance.
i want the output in best time.
My query is
select t.row_mod,
t.widget_info_id,
t.widget_name,
t.text1,
m.pretty_name,
w.website_id,
w.fol3_website_id
from fbw_info_text t,
fbw_info_meta m,
fol3_website w
where t.widget_info_id = m.widget_info_id
and t.widget_name = m.widget_name
and (
m.widget_type = 'checkbox'
or t.widget_name in (
'ccapi_approved_transactions_msg',
'ccapi_declined_transactions_msg',
'ccapi_failed_transactions_msg'
)
)
and t.website_id = w.website_id
and (
(t.row_mod >= '2013-10-24 20:57:32'
and t.row_mod <= '2013-10-24 20:59:32')
or
(m.row_mod >= '2013-10-24 20:57:32'
and m.row_mod <= '2013-10-24 20:59:32')
)
order by widget_info_id, widget_name;
Explain Plan:
+----+-------------+-------+-------+-------------------------------------+----------+---------+----------------------------------------+-------+----------------------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+-------+-------------------------------------+----------+---------+----------------------------------------+-------+----------------------------------------------+
| 1 | SIMPLE | w | index | idx_1055,idx_1786 | idx_1522 | 4 | NULL | 25953 | Using index; Using temporary; Using filesort |
| 1 | SIMPLE | t | ref | idx_4639,idx_1055,idx_2718,idx_3388 | idx_1055 | 53 | cms.w.website_id | 12 | Using where |
| 1 | SIMPLE | m | ref | idx_2718 | idx_2718 | 105 | cms.t.widget_name,cms.t.widget_info_id | 1 | Using where |
+----+-------------+-------+-------+-------------------------------------+----------+---------+----------------------------------------+-------+----------------------------------------------+
3 rows in set (0.01 sec)
Table structures
mysql> show create table fbw_info_text\G
*************************** 1. row ***************************
Table: fbw_info_text
Create Table: CREATE TABLE `fbw_info_text` (
`row_mod` datetime DEFAULT NULL,
`row_create` datetime DEFAULT NULL,
`widget_info_id` varchar(50) COLLATE latin1_bin DEFAULT NULL,
`widget_name` varchar(50) COLLATE latin1_bin DEFAULT NULL,
`website_id` varchar(50) COLLATE latin1_bin DEFAULT NULL,
`text1` longtext COLLATE latin1_bin,
`text2` longtext COLLATE latin1_bin,
`submitted_user_id` varchar(50) COLLATE latin1_bin DEFAULT NULL,
`use_default` varchar(1) COLLATE latin1_bin DEFAULT NULL,
`active_flag` varchar(1) COLLATE latin1_bin DEFAULT NULL,
`status` varchar(1) COLLATE latin1_bin DEFAULT NULL,
UNIQUE KEY `idx_4639` (`website_id`,`widget_info_id`,`widget_name`,`status`),
KEY `idx_1055` (`website_id`),
KEY `idx_2718` (`widget_info_id`,`widget_name`),
KEY `idx_3388` (`widget_info_id`,`website_id`,`status`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_bin
1 row in set (0.01 sec)
mysql> show create table fbw_info_meta\G
*************************** 1. row ***************************
Table: fbw_info_meta
Create Table: CREATE TABLE `fbw_info_meta` (
`row_mod` datetime DEFAULT NULL,
`row_create` datetime DEFAULT NULL,
`widget_name` varchar(50) COLLATE latin1_bin NOT NULL,
`pretty_name` varchar(255) COLLATE latin1_bin DEFAULT NULL,
`widget_info_id` varchar(50) COLLATE latin1_bin DEFAULT NULL,
`widget_type` varchar(50) COLLATE latin1_bin DEFAULT NULL,
`needs_approval` varchar(1) COLLATE latin1_bin DEFAULT NULL,
`widget_value` longtext COLLATE latin1_bin,
`widget_order` int(11) DEFAULT NULL,
`widget_attributes` varchar(255) COLLATE latin1_bin DEFAULT NULL,
`capability_name` varchar(30) COLLATE latin1_bin DEFAULT NULL,
`design_type` varchar(50) COLLATE latin1_bin DEFAULT NULL,
`on_approval_hook` longtext COLLATE latin1_bin,
`display_hook` longtext COLLATE latin1_bin,
`status` varchar(1) COLLATE latin1_bin DEFAULT NULL,
`needs_archive` varchar(1) COLLATE latin1_bin DEFAULT NULL,
UNIQUE KEY `idx_2718` (`widget_name`,`widget_info_id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_bin
1 row in set (0.00 sec)
mysql> show create table fol3_website\G
*************************** 1. row ***************************
Table: fol3_website
Create Table: CREATE TABLE `fol3_website` (
`row_mod` datetime DEFAULT NULL,
`row_create` datetime DEFAULT NULL,
`fol3_website_id` int(11) NOT NULL,
`website_id` varchar(50) COLLATE latin1_bin NOT NULL,
`activate_default_host` int(11) DEFAULT '0',
`active` int(11) NOT NULL DEFAULT '1',
`advance_notice_days` int(11) DEFAULT '0',
`catrequest` int(11) DEFAULT '0',
`chain` int(11) DEFAULT NULL,
`color_scheme` varchar(30) COLLATE latin1_bin DEFAULT NULL,
`conversion_rate` int(11) DEFAULT '0',
`comment` varchar(255) COLLATE latin1_bin DEFAULT NULL,
`creation_date` datetime DEFAULT NULL,
`defunct_2` varchar(5) COLLATE latin1_bin DEFAULT NULL,
`default_website` varchar(50) COLLATE latin1_bin NOT NULL,
`designtype` varchar(25) COLLATE latin1_bin DEFAULT NULL,
`key_contact_name` varchar(55) COLLATE latin1_bin DEFAULT NULL,
`key_contact_phone` varchar(60) COLLATE latin1_bin DEFAULT NULL,
`language_id` varchar(5) COLLATE latin1_bin DEFAULT NULL,
`defunct_0` varchar(10) COLLATE latin1_bin DEFAULT NULL,
`mercury` int(11) NOT NULL DEFAULT '1',
`mgnt_defaults_last_applied` datetime DEFAULT NULL,
`rank` varchar(10) COLLATE latin1_bin DEFAULT NULL,
`return_url` varchar(255) COLLATE latin1_bin DEFAULT NULL,
`defunct_1` varchar(10) COLLATE latin1_bin DEFAULT NULL,
`store_id` varchar(15) COLLATE latin1_bin NOT NULL,
`defunct_3` varchar(10) COLLATE latin1_bin DEFAULT NULL,
`display_website_url` varchar(25) COLLATE latin1_bin DEFAULT NULL,
`webloyalty` int(11) DEFAULT NULL,
`name` varchar(255) COLLATE latin1_bin DEFAULT NULL,
`transmission_type` int(11) DEFAULT NULL,
`segment` int(11) DEFAULT NULL,
`site_id` varchar(25) COLLATE latin1_bin DEFAULT NULL,
`canonical_status` int(1) DEFAULT '0',
`canonical_domain` varchar(100) COLLATE latin1_bin DEFAULT NULL,
`mobile_site_active` tinyint(1) DEFAULT '1',
UNIQUE KEY `idx_1055` (`website_id`),
UNIQUE KEY `idx_1522` (`fol3_website_id`),
UNIQUE KEY `idx_1786` (`website_id`,`active`),
KEY `idx_1867` (`transmission_type`),
KEY `idx_857` (`store_id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_bin
1 row in set (0.00 sec)
You can try SHOW Profiling functionality of MySQL to find out where most of the time has been taken by a query execution and optimize based on result:
set profiling=1;
Run your slow query (eg SELECT * FROM table WHERE name='xxx';
SHOW PROFILES;
http://dev.mysql.com/doc/refman/5.0/en/show-profile.html
Analyze EXPLAIN EXTENED output and optimize query accourdingly and profile the query again to see gain in performance.
My query is running more than 4 seconds.
i want result in less than 1 second
help me here.
Query:
SELECT a.index_id,
title
FROM fb_indices a,
fb_catalog_indices b FORCE INDEX (idx_1986)
WHERE a.index_id = b.index_id
AND type = 'international'
AND title IS NOT NULL
Explain Plan:
mysql> explain select a.index_id,title from fb_indices a, fb_catalog_indices b force index (idx_1986) where a.index_id = b.index_id and type='international' and title is not NULL;
+----+-------------+-------+------+-----------------+----------+---------+----------------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+------+-----------------+----------+---------+----------------+------+-------------+
| 1 | SIMPLE | a | ref | idx_836,idx_450 | idx_450 | 53 | const | 79 | Using where |
| 1 | SIMPLE | b | ref | idx_1986 | idx_1986 | 103 | cms.a.index_id | 590 | Using where |
+----+-------------+-------+------+-----------------+----------+---------+----------------+------+-------------+
2 rows in set (0.00 sec)
Structure:
mysql> show create table fb_indices\G
*************************** 1. row ***************************
Table: fb_indices
Create Table: CREATE TABLE `fb_indices` (
`row_mod` datetime DEFAULT NULL,
`row_create` datetime DEFAULT NULL,
`index_id` varchar(100) COLLATE latin1_bin DEFAULT NULL,
`description` varchar(255) COLLATE latin1_bin DEFAULT NULL,
`country_id` varchar(2) COLLATE latin1_bin DEFAULT NULL,
`index_level` int(11) DEFAULT NULL,
`type` varchar(50) COLLATE latin1_bin DEFAULT NULL,
`approval_flag` int(11) DEFAULT NULL,
`username` varchar(255) COLLATE latin1_bin DEFAULT NULL,
`search_product_type` int(11) DEFAULT NULL,
`search_color` int(11) DEFAULT NULL,
`search_price` int(11) DEFAULT NULL,
UNIQUE KEY `idx_836` (`index_id`),
KEY `idx_450` (`type`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_bin
1 row in set (0.00 sec)
mysql> show create table fb_catalog_indices\G
*************************** 1. row ***************************
Table: fb_catalog_indices
Create Table: CREATE TABLE `fb_catalog_indices` (
`row_mod` datetime DEFAULT NULL,
`row_create` datetime DEFAULT NULL,
`index_id` varchar(100) COLLATE latin1_bin DEFAULT NULL,
`website_id` varchar(50) COLLATE latin1_bin DEFAULT NULL,
`title` varchar(100) COLLATE latin1_bin DEFAULT NULL,
`subheading` longtext COLLATE latin1_bin,
`product_ids` longtext COLLATE latin1_bin,
`sub_index_ids` longtext COLLATE latin1_bin,
`mapped_index_ids` longtext COLLATE latin1_bin,
`username` varchar(100) COLLATE latin1_bin DEFAULT NULL,
`content` longtext COLLATE latin1_bin,
`meta_description` longtext COLLATE latin1_bin,
`meta_tag_keyword` longtext COLLATE latin1_bin,
`mapped_link_text` longtext COLLATE latin1_bin,
`mapped_alt_tags` longtext COLLATE latin1_bin,
`long_title` varchar(255) COLLATE latin1_bin DEFAULT NULL,
`html_content` longtext COLLATE latin1_bin,
`use_html_content` int(11) DEFAULT '0',
`flash_size` longtext COLLATE latin1_bin,
`custom_index_ids` longtext COLLATE latin1_bin,
`html_header_1` longtext COLLATE latin1_bin,
`html_header_2` longtext COLLATE latin1_bin,
`search_product_type` int(11) DEFAULT NULL,
`search_color` int(11) DEFAULT NULL,
`search_price` int(11) DEFAULT NULL,
`disable_rankings` int(11) DEFAULT NULL,
`html_footer_1` longtext COLLATE latin1_bin,
`dramashot_html` longtext COLLATE latin1_bin,
`quickshop_image` longtext COLLATE latin1_bin,
`sort_by_price_css` longtext COLLATE latin1_bin,
`pagination_css` longtext COLLATE latin1_bin,
`suppress_navigation` int(11) DEFAULT NULL,
`suppress_quickshop_image` int(11) DEFAULT NULL,
`mvt_control_script` longtext COLLATE latin1_bin,
`mvt_tracking_script` longtext COLLATE latin1_bin,
`enable_gbb_mouse` int(11) DEFAULT NULL,
`enable_gbb_click` int(11) DEFAULT NULL,
`last_modified_time` datetime DEFAULT NULL,
`seo_footer_content` longtext COLLATE latin1_bin,
`alternate_gfi` int(11) DEFAULT NULL,
`zip_finder_html_content` longtext COLLATE latin1_bin,
`disable_quick_view_widget` int(11) DEFAULT NULL,
`indexpromo_title` varchar(255) COLLATE latin1_bin DEFAULT NULL,
`indexpromo_style` longtext COLLATE latin1_bin,
`background_color` text COLLATE latin1_bin,
`sameday_text` text COLLATE latin1_bin,
`productdesc_text` text COLLATE latin1_bin,
`productprice_text` text COLLATE latin1_bin,
`gbbcatalog_text` text COLLATE latin1_bin,
`max_products_display` int(11) DEFAULT NULL,
UNIQUE KEY `idx_1986` (`index_id`,`website_id`),
KEY `idx_1055` (`website_id`),
KEY `idx_836` (`index_id`),
KEY `idx_1812` (`last_modified_time`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_bin
1 row in set (0.00 sec)
Create following index:
CREATE INDEX idx_999 ON fb_indices (index_id, type);
After that, this query is equivalent to yours and should work fast:
SELECT a.index_id,
b.title
FROM fb_indices a
JOIN fb_catalog_indices b ON (a.index_id = b.index_id)
WHERE a.type = 'international'
AND b.title IS NOT NULL
Tip: try not to force index usage - in your case, it was hurting. Instead, create an appropriate index.
SELECT a.index_id,
title
FROM fb_indices a,
(
SELECT
index_id
FROM
fb_catalog_indices
WHERE
type = 'international'
) as b
WHERE a.index_id = b.index_id
AND title IS NOT NULL