slow mysql query with inner join 0846 sec - mysql

I have another problem when i used query with INNER JOIN
this query
SELECT *
FROM `engine4_product_file` INNER JOIN
`engine4_file`
ON engine4_product_file.fid = engine4_file.id
WHERE engine4_product_file.pid IN (3347,3346,3345,3343,3342,3337) and
engine4_file.active = 1 AND
engine4_file.ext IN ('jpg','gif','png','jpeg')
and this create table engine4_product_file
CREATE TABLE `engine4_product_file` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`fid` int(11) NOT NULL,
`pid` int(11) NOT NULL,
PRIMARY KEY (`id`),
KEY `engine4_product_file` (`fid`),
KEY `pid` (`pid`)
) ENGINE=InnoDB AUTO_INCREMENT=6549 DEFAULT CHARSET=latin1
and this create table engine4_file
CREATE TABLE `engine4_file` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`uid` int(11) NOT NULL,
`name` longtext CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL,
`url` longtext CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL,
`date` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`active` int(11) NOT NULL DEFAULT '1',
`size` int(11) DEFAULT NULL,
`ext` varchar(10) DEFAULT NULL,
`folder` int(11) NOT NULL DEFAULT '0',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=48801 DEFAULT CHARSET=latin1
this explain
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE engine4_product_file range engine4_product_file,pid pid 4 NULL 30 Using where
1 SIMPLE engine4_file eq_ref PRIMARY PRIMARY 4 akafine_social2.engine4_product_file.fid 1 Using where

Change your WHERE conditions
WHERE engine4_file.active = 1 AND
engine4_file.ext IN ('jpg','gif','png','jpeg') AND
engine4_product_file.pid IN (3347,3346,3345,3343,3342,3337)
Add an index
ALTER TABLE engine4_file ADD KEY (active,ext)

Related

Unable to optimize queries - Bad design or Bad query or Both?

CREATE TABLE `questions` (
`question_id` int(5) unsigned NOT NULL AUTO_INCREMENT,
`FK_quiz_id` int(5) unsigned NOT NULL,
`question_identify_text` varchar(100) COLLATE utf8_unicode_ci NOT NULL,
PRIMARY KEY (`question_id`),
KEY `FK_quiz_id` (`FK_quiz_id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci
CREATE TABLE `question_multilingual` (
`question_multilingual_id` int(5) unsigned NOT NULL AUTO_INCREMENT,
`FK_question_id` int(5) unsigned NOT NULL,
`FK_language_id` smallint(3) unsigned NOT NULL,
`question` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
PRIMARY KEY (`question_multilingual_id`),
UNIQUE KEY `FK_question_id` (`FK_question_id`,`FK_language_id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci
CREATE TABLE `choices` (
`choice_id` int(5) unsigned NOT NULL AUTO_INCREMENT,
`FK_question_id` int(5) unsigned NOT NULL,
`choice_identify_text` varchar(100) COLLATE utf8_unicode_ci NOT NULL,
PRIMARY KEY (`choice_id`),
KEY `FK_question_id` (`FK_question_id`)
) ENGINE=MyISAM AUTO_INCREMENT=6 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci
CREATE TABLE `choice_multilingual` (
`choice_multilingual_id` int(5) unsigned NOT NULL AUTO_INCREMENT,
`FK_choice_id` int(5) unsigned NOT NULL,
`FK_language_id` smallint(3) unsigned NOT NULL,
`choice` varchar(100) COLLATE utf8_unicode_ci NOT NULL,
PRIMARY KEY (`choice_multilingual_id`),
UNIQUE KEY `FK_choice_id` (`FK_choice_id`,`FK_language_id`)
) ENGINE=InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci
These are the table structures.
EXPLAIN SELECT * FROM `questions` inner join question_multilingual on question_multilingual.FK_question_id = questions.question_id AND question_multilingual.FK_language_id = 1 INNER JOIN choices ON choices.FK_question_id = questions.question_id INNER JOIN choice_multilingual ON choice_multilingual.FK_choice_id = choices.choice_id AND choice_multilingual.FK_language_id = 1 WHERE FK_quiz_id = 1
1 SIMPLE choice_multilingual NULL ALL FK_choice_id NULL NULL NULL 14 10.00 Using where
1 SIMPLE question_multilingual NULL ref FK_question_id,FK_language_id FK_language_id 2 const 2 100.00 NULL
1 SIMPLE choices NULL eq_ref PRIMARY,FK_question_id PRIMARY 4 quizzes.choice_multilingual.FK_choice_id 1 14.29 Using where
1 SIMPLE questions NULL eq_ref PRIMARY,FK_quiz_id PRIMARY 4 quizzes.question_multilingual.FK_question_id 1 100.00 Using where
I tried to change composite index, single index. Tried to add columns.
The results varies but not getting the optimized one whatever i do.

MySQL use separate indices for JOIN and GROUP BY

I am trying to execute following query
SELECT
a.sessionID AS `sessionID`,
firstSeen, birthday, gender,
isAnonymous, LanguageCode
FROM transactions AS trx
INNER JOIN actions AS a ON a.sessionID = trx.SessionID
WHERE a.ActionType = 'PURCHASE'
GROUP BY trx.TransactionNumber
Explain provides the following output
1 SIMPLE trx ALL TransactionNumber,SessionID NULL NULL NULL 225036 Using temporary; Using filesort
1 SIMPLE a ref sessionID sessionID 98 infinitiExport.trx.SessionID 1 Using index
The problem is that I am trying to use one field for join and different field for GROUP BY.
How can I tell MySQL to use different indices for same table?
CREATE TABLE `transactions` (
`SessionID` varchar(32) NOT NULL DEFAULT '',
`date` datetime DEFAULT NULL,
`TransactionNumber` varchar(32) NOT NULL DEFAULT '',
`CustomerECommerceTrackID` int(11) DEFAULT NULL,
`SKU` varchar(45) DEFAULT NULL,
`AmountPaid` double DEFAULT NULL,
`Currency` varchar(10) DEFAULT NULL,
`Quantity` int(11) DEFAULT NULL,
`Name` tinytext NOT NULL,
`Category` varchar(45) NOT NULL DEFAULT '',
`customerInfoXML` text,
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
PRIMARY KEY (`id`),
KEY `TransactionNumber` (`TransactionNumber`),
KEY `SessionID` (`SessionID`)
) ENGINE=InnoDB AUTO_INCREMENT=212007 DEFAULT CHARSET=utf8;
CREATE TABLE `actions` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`sessionActionDate` datetime DEFAULT NULL,
`actionURL` varchar(255) DEFAULT NULL,
`sessionID` varchar(32) NOT NULL DEFAULT '',
`ActionType` varchar(64) DEFAULT NULL,
`CustomerID` int(11) DEFAULT NULL,
`IPAddressID` int(11) DEFAULT NULL,
`CustomerDeviceID` int(11) DEFAULT NULL,
`customerInfoXML` text,
PRIMARY KEY (`id`),
KEY `ActionType` (`ActionType`),
KEY `CustomerDeviceID` (`CustomerDeviceID`),
KEY `sessionID` (`sessionID`)
) ENGINE=InnoDB AUTO_INCREMENT=15042833 DEFAULT CHARSET=utf8;
Thanks
EDIT 1: My indexes were broken, I had to add (SessionID, TransactionNumber) index to transactions table, however now, when I try to include trx.customerInfoXML table mysql stops using index
EDIT 2 Another answer does not really solved my problem because it's not standard sql syntax and generally not a good idea to force indices.
For ORM users such syntax is a unattainable luxury.
EDIT 3 I updated my indices and it solved the problem, see EDIT 1

verey Slow when use IN in table mysql 46.4878 sec

Very very slow in the query when using IN
this query
SELECT *
FROM engine4_comment
WHERE sid IN (10,12,548,2110,5241,1255)
and this create table
CREATE TABLE `engine4_comment` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`sid` int(11) NOT NULL,
`rid` int(11) NOT NULL DEFAULT '0',
`uid` int(11) NOT NULL,
`text` longtext COLLATE utf8_unicode_ci NOT NULL,
`date` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`active` int(11) NOT NULL DEFAULT '1',
`deleted` int(11) NOT NULL DEFAULT '0',
`deleted_reason` text CHARACTER SET latin1 NOT NULL,
`send_email` int(11) NOT NULL DEFAULT '1',
`user_active` tinyint(4) NOT NULL DEFAULT '1',
`dep_active` tinyint(4) NOT NULL DEFAULT '1',
PRIMARY KEY (`id`),
KEY `dat_idx` (`date`),
KEY `rid_idx` (`rid`),
KEY `rsid_idx` (`rid`,`sid`)
) ENGINE=InnoDB AUTO_INCREMENT=719329 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci
and when use explaine explain SELECT * FROMengine4_commentWHERE sid IN (10,12,548,2110,5241,1255)
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE engine4_comment ALL NULL NULL NULL NULL 875583 Using where
This is your query:
SELECT *
FROM engine4_comment
WHERE sid IN (10,12,548,2110,5241,1255)
For performance, you want an index on sid. Either include a KEY statement in the create table. Or, explicitly create an index:
create index idx_engine4_comment_sid on engine4_comment(sid);
Note that the index rsid_idx doesn't help for this query, because sid is the second column. An index on (sid, rid) would benefit this query.

fix Using index, Using temporary, Using filesort

i have such 3 tables. Im trying to Left Join them
SELECT `t`.`title` AS `category_title`,`t`.`id` AS `category_id`, `st`.`title` AS
`subcategory_title`, `st`.`id` AS `subcategory_id`, `st`.`parent_id` AS
`subcategory_parent`, `n`.`title` AS `news_title`,`n`.`id` AS `news_id` FROM
`t_categories` `t` LEFT JOIN t_categories AS `st` ON `st`.`parent_id`=t.`id` LEFT JOIN
t_newsrelations AS `nr` ON `nr`.`category_id`=st.`id` LEFT JOIN t_news AS `n` ON
`n`.`id`=nr.`news_id` WHERE `t`.`enabled` = 1 AND `n`.`enabled` = 1 AND `n`.`type`!=1 AND
`n`.`type`!=5 ORDER BY `t`.`position`,`st`.`position`,`n`.`position` ASC
here is the structure of tables
CREATE TABLE IF NOT EXISTS `t_categories` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`parent_id` int(11) NOT NULL,
`title` tinytext NOT NULL,
`position` tinyint(4) unsigned NOT NULL DEFAULT '0',
`type` tinyint(1) unsigned NOT NULL,
`enabled` tinyint(1) unsigned NOT NULL DEFAULT '1',
UNIQUE KEY `id` (`id`),
KEY `type` (`type`),
KEY `parent_id` (`parent_id`),
KEY `enabled` (`enabled`),
KEY `id_parent_position_enabled` (`id`,`parent_id`,`position`,`enabled`),
KEY `position` (`position`),
KEY `parent_id_2` (`parent_id`,`enabled`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 ;
CREATE TABLE IF NOT EXISTS `t_news` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`title` tinytext NOT NULL,
`m_title` tinytext NOT NULL,
`url` varchar(2000) NOT NULL,
`keywords` text NOT NULL,
`description` text NOT NULL,
`body` longtext NOT NULL,
`position` tinyint(4) unsigned NOT NULL DEFAULT '0',
`type` tinyint(1) unsigned NOT NULL,
`city_id` int(4) NOT NULL,
`quickmenu_enabled` tinyint(1) unsigned NOT NULL DEFAULT '0',
`quickmenu` text NOT NULL,
`enabled` tinyint(1) unsigned NOT NULL DEFAULT '1',
PRIMARY KEY (`id`),
UNIQUE KEY `id` (`id`),
KEY `position` (`position`),
KEY `type` (`type`),
KEY `city_id` (`city_id`),
KEY `url` (`url`(333)),
KEY `quickmenu_enabled` (`quickmenu_enabled`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 ;
CREATE TABLE IF NOT EXISTS `t_newsrelations` (
`category_id` int(11) NOT NULL,
`news_id` int(11) unsigned NOT NULL,
KEY `category_id` (`category_id`),
KEY `news_id` (`news_id`),
KEY `category_id_2` (`category_id`,`news_id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
And SELECT EXPLAIN shows me
t_newsrelations is intermediate table. Table t_categories contains categories and subcategories linked by parent_id column. Each item from t_news can be a member of more than one subcategories thats why they linked through t_newsrelations
how to optimise a query? Why it shows Using index, Using temporary, Using filesort?
ORDER BY `t`.`position`,`st`.`position`,`n`.`position` ASC
You can't eliminate the temp table and filesort in this query, given the tables you have, because you're sorting on columns from multiple tables. Optimizing sorting means using an index so that the query fetches rows in the order you want them. But there's no way in MySQL to create an index that spans multiple tables.
The only way to fix this is to denormalize until all three columns are in a single table, and create one index over the three columns. But denormalization comes with its own downsides.

How to set correct index for this MySql query?

I have this query showing up in MySql slow query log. (It is not slow, but it is not using indexes right). I need some help on how to set up the index right.
SELECT tbladded.amount*SUM(tbladdeditem.amount)
FROM tbladded
INNER JOIN tbladdeditem ON tbladded.addedid = tbladdeditem.addedid AND tbladdeditem.deleted='False'
WHERE tbladded.userid=100
AND tbladded.date='2012-01-01'
AND tbladded.deleted='False'
GROUP BY tbladded.addedid
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE tbladded ref PRIMARY,userid_date userid_date 8 const,const 1 Using where
1 SIMPLE tbladdeditem ref addedid addedid 5 tbladded.addedid 1 Using where
This is how the tables look like:
CREATE TABLE `tbladded` (
`addedid` int(11) NOT NULL AUTO_INCREMENT,
`amount` double DEFAULT NULL,
`date` date DEFAULT NULL,
`userid` mediumint(9) DEFAULT NULL,
`deleted` enum('False','True') CHARACTER SET latin1 DEFAULT 'False',
PRIMARY KEY (`addedid`),
KEY `userid_date` (`userid`,`date`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `tbladdeditem` (
`addeditemid` int(11) NOT NULL AUTO_INCREMENT,
`amount` double DEFAULT NULL,
`addedid` int(11) DEFAULT NULL,
`userid` mediumint(9) DEFAULT NULL,
`deleted` enum('False','True') CHARACTER SET latin1 DEFAULT 'False',
PRIMARY KEY (`addeditemid`),
KEY `addedid` (`addedid`),
KEY `userid` (`userid`),
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
try this:
ALTER TABLE `tbladded` ADD INDEX
`tbladdedIndex` (`userid`, `date`, `deleted`);