MySQL query optimization improvement - mysql

Hello all I have a MySQL query that fetches data from more than on tables. Here is my query
SELECT
user_id as id,
user_name as name,
user_phone as phone,
user_email as email,
user_address1 as address1,
user_address2 as address2,
user_city as city,
user_state as state,
user_country as country,
user_available as available,
user_location as location,
user_latitude as latitude,
user_longitude as longitude,
user_description as description,
user_company as company,
user_gender as gender,
(SELECT MIN(service_price) FROM service WHERE service.user_id = a.user_id) as price,
(SELECT service_recomanded FROM service WHERE service.user_id = a.user_id ORDER BY service.service_price ASC LIMIT 1) as recomandad,
verified_email,
verified_facebook,
verified_phone,
verified_twitter,
(SELECT providerphoto_name FROM providerphoto WHERE providerphoto.user_id = a.user_id ORDER BY providerphoto_order ASC LIMIT 1 ) as photo,
(SELECT ROUND( AVG(review_rate),2) FROM review WHERE review.user_id = a.user_id ) AS rate,
(SELECT service_ICOC FROM service WHERE service.user_id = a.user_id ORDER BY service_price ASC LIMIT 1) as type
FROM
user a
WHERE a.user_type = 'provider'
AND a.user_active=1
AND a.user_deleted=0
It gets data from user table, service table, review table and providerphoto table. It works too but the execution time is very slow. I guess to make it a single query and avoid the inner five queries may run it fast. Any help?
Table structures.
--
-- Table structure for table `providerphoto`
--
CREATE TABLE IF NOT EXISTS `providerphoto` (
`providerphoto_id` int(11) NOT NULL AUTO_INCREMENT,
`user_id` int(11) NOT NULL,
`providerphoto_file` varchar(256) COLLATE utf8_unicode_ci NOT NULL DEFAULT '',
`providerphoto_name` varchar(256) COLLATE utf8_unicode_ci NOT NULL DEFAULT '',
`providerphoto_date` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`providerphoto_order` int(11) NOT NULL DEFAULT '0',
PRIMARY KEY (`providerphoto_id`),
KEY `user_id` (`user_id`),
KEY `providerphoto` (`user_id`,`providerphoto_name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=487 ;
-- --------------------------------------------------------
--
-- Table structure for table `review`
--
CREATE TABLE IF NOT EXISTS `review` (
`review_id` int(11) NOT NULL AUTO_INCREMENT,
`review_title` varchar(256) COLLATE utf8_unicode_ci NOT NULL,
`user_id` int(11) NOT NULL,
`review_date` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`review_content` text COLLATE utf8_unicode_ci NOT NULL,
`review_user_id` int(11) NOT NULL,
`review_rate` int(10) NOT NULL DEFAULT '1',
`review_tip` int(11) NOT NULL DEFAULT '0',
`service_booked` int(11) NOT NULL DEFAULT '0',
PRIMARY KEY (`review_id`),
KEY `user_id` (`user_id`),
KEY `review_date` (`review_date`),
KEY `review_user_id` (`review_user_id`),
KEY `review_rate` (`review_rate`),
KEY `review_tip` (`review_tip`),
KEY `service_booked` (`service_booked`),
KEY `review` (`user_id`,`review_rate`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=97 ;
-- --------------------------------------------------------
--
-- Table structure for table `service`
--
CREATE TABLE IF NOT EXISTS `service` (
`service_id` int(11) NOT NULL AUTO_INCREMENT,
`service_name` varchar(45) COLLATE utf8_unicode_ci DEFAULT NULL,
`user_id` int(11) DEFAULT NULL,
`service_created_by` int(11) NOT NULL DEFAULT '0',
`service_ICOC` varchar(256) COLLATE utf8_unicode_ci NOT NULL DEFAULT '',
`service_price` int(11) NOT NULL,
`service_date_added` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`service_date_expire` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
`service_time` varchar(256) COLLATE utf8_unicode_ci NOT NULL DEFAULT '0',
`service_rate` varchar(256) COLLATE utf8_unicode_ci NOT NULL DEFAULT '0',
`service_type` int(10) NOT NULL DEFAULT '1' COMMENT '1-in call, 2-out call, 3-in&out call',
`service_recomanded` int(2) NOT NULL DEFAULT '0',
`service_genre` varchar(100) COLLATE utf8_unicode_ci NOT NULL,
`service_message` text COLLATE utf8_unicode_ci NOT NULL,
PRIMARY KEY (`service_id`),
KEY `user_id` (`user_id`),
KEY `service_ICOC` (`service_ICOC`(255)),
KEY `service` (`user_id`,`service_price`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=854 ;
-- --------------------------------------------------------
--
-- Table structure for table `user`
--
CREATE TABLE IF NOT EXISTS `user` (
`user_id` int(11) NOT NULL AUTO_INCREMENT,
`user_name` varchar(256) COLLATE utf8_unicode_ci DEFAULT NULL,
`user_password` varchar(256) COLLATE utf8_unicode_ci NOT NULL,
`user_email` varchar(256) COLLATE utf8_unicode_ci DEFAULT NULL,
`user_phone` varchar(256) COLLATE utf8_unicode_ci DEFAULT NULL,
`user_address1` text COLLATE utf8_unicode_ci,
`user_address2` text COLLATE utf8_unicode_ci NOT NULL,
`user_city` varchar(256) COLLATE utf8_unicode_ci NOT NULL,
`user_state` varchar(256) COLLATE utf8_unicode_ci NOT NULL,
`user_country` varchar(256) COLLATE utf8_unicode_ci NOT NULL,
`user_company` varchar(256) COLLATE utf8_unicode_ci NOT NULL,
`user_birthday` date DEFAULT NULL,
`user_register_date` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
`user_type` enum('provider','client') COLLATE utf8_unicode_ci DEFAULT NULL,
`user_description` text COLLATE utf8_unicode_ci NOT NULL,
`user_available` int(10) NOT NULL DEFAULT '1',
`verified_email` tinyint(1) NOT NULL DEFAULT '0',
`verified_facebook` tinyint(1) NOT NULL DEFAULT '0',
`verified_phone` tinyint(1) NOT NULL DEFAULT '0',
`verified_twitter` tinyint(1) NOT NULL DEFAULT '0',
`user_facebook_friends` int(11) NOT NULL DEFAULT '0',
`user_twitter_friends` int(11) NOT NULL DEFAULT '0',
`user_longitude` decimal(10,5) NOT NULL DEFAULT '0.00000',
`user_latitude` decimal(10,5) NOT NULL DEFAULT '0.00000',
`user_deleted` tinyint(4) NOT NULL DEFAULT '0',
`user_gender` int(11) NOT NULL DEFAULT '0',
`user_facebook_token` varchar(200) COLLATE utf8_unicode_ci NOT NULL,
`user_active` tinyint(4) NOT NULL DEFAULT '1',
`user_location` varchar(200) COLLATE utf8_unicode_ci NOT NULL,
`user_push_notification_token` varchar(100) COLLATE utf8_unicode_ci NOT NULL,
`user_timezone_diff` int(11) NOT NULL DEFAULT '0',
`balanced_uri` text COLLATE utf8_unicode_ci NOT NULL,
`user_reset_passwd_token` varchar(200) COLLATE utf8_unicode_ci NOT NULL,
`is_test_user` int(11) NOT NULL DEFAULT '0',
PRIMARY KEY (`user_id`),
KEY `deleted_idx` (`user_deleted`),
KEY `email_idx` (`user_email`(255))
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=426 ;

You can probably just add indexes to speed up the query. Try adding the following indexes:
service(user_id, service_price)
providerphoto(user_id, providerphoto_order)
review(user_id, review_rate)

Something like this. This will return all the values for the users as I did not use the ORDER and LIMIT in the query. This is just for the approach.
SELECT
a.user_id as id,
user_name as name,
user_phone as phone,
user_email as email,
user_address1 as address1,
user_address2 as address2,
user_city as city,
user_state as state,
user_country as country,
user_available as available,
user_location as location,
user_latitude as latitude,
user_longitude as longitude,
user_description as description,
user_company as company,
user_gender as gender,
MIN(s.service_price) as price,
s.service_recomanded as recomandad,
verified_email,
verified_facebook,
verified_phone,
verified_twitter,
pp.providerphoto_name as photo,
ROUND( AVG(r.review_rate),2) as rate,
s.service_ICOC as type
FROM
user a LEFT JOIN service s on s.user_id = a.user_id LEFT JOIN providerphoto pp on pp.user_id = a.user_id LEFT JOIN review r on r.user_id = a.user_id
WHERE a.user_type = 'provider'
AND a.user_active=1
AND a.user_deleted=0;

First thing I would do is index user.user_type, user.user_deleted and user.user_active to let the optimizer quickly start with a smaller set of user records to have to deal with.
Do you mean to allow service.user_id to be NULL? That seems like a mistake.
Also you may want to throw indexes on any columns where you're doing an ORDER BY.
The best way to find out what is slow in this query is to do a EXPLAIN QUERY and analyze what it tells you. We can help you with that as well.

Related

MySQL QUERY for photo ranking

I have 2 tables:
CREATE TABLE `psPhotosRating` (
`id_photo_rating` int(11) NOT NULL,
`id_user` int(11) NOT NULL,
`id_uploaded_files` int(11) NOT NULL,
`rating` int(2) NOT NULL,
`timestamp` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
CREATE TABLE `psUploadedFiles2` (
`id_uploaded_files` int(10) UNSIGNED NOT NULL,
`enable` char(1) COLLATE utf8_unicode_ci NOT NULL DEFAULT '0',
`id_user` int(11) NOT NULL DEFAULT '0',
`file_path` varchar(150) COLLATE utf8_unicode_ci NOT NULL,
`file_name` varchar(75) COLLATE utf8_unicode_ci NOT NULL,
`creation_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`category` bigint(20) NOT NULL DEFAULT '0',
`tags` text COLLATE utf8_unicode_ci,
`description` mediumtext COLLATE utf8_unicode_ci,
`promo_in_front` char(1) COLLATE utf8_unicode_ci NOT NULL DEFAULT '0',
`count` bigint(20) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
ALTER TABLE `psPhotosRating`
ADD PRIMARY KEY (`id_photo_rating`);
ALTER TABLE `psPhotosRating`
MODIFY `id_photo_rating` int(11) NOT NULL AUTO_INCREMENT;
ALTER TABLE `psUploadedFiles2`
MODIFY `id_uploaded_files` int(10) UNSIGNED NOT NULL AUTO_INCREMENT;
COMMIT;
psUploadedFiles2 - this is the "photo database"
psPhotosRating - table with votes cast for each photo from psUploadedFiles2
Not every picture has votes.
I need a SQL query displaying a list of images (psUploadedFiles2) sorted by the psPhotosRating rank (number of votes cast).
Does anyone know how to do it?
I think you can just join here second table and count results:
SELECT count(rat.id_uploaded_files ) as rating, ps.*
FROM psUploadedFiles2 ps
JOIN psPhotosRating rat ON ps.id_uploaded_files = rat.id_uploaded_files
ORDER BY rating DESC;

MYSQL Multiple tables left joins with conditions and duplicate tables

I can't seem to produce a valid MySQL (version MySQL 5.6).
I have the bellow SQL that works well but it returns records only when all conditions are satisfied. I need it to return records for all users having the missing data as NULL.
So LEFT JOINS would be the way (unless there is a better way).
Please note about the usage of one of the tables twice.
SELECT
users.email,
ufs.first_name,
ufs.last_name,
country_label.label as country,
interest_label.label as interest,
points.actions,
points.badges,
points.points
FROM
site_users users,
site_user_fields_values interest,
site_user_fields_options interest_label,
site_user_fields_values country,
site_user_fields_options country_label,
points_users points,
site_user_fields_search ufs
WHERE
interest.field_id = 15 AND
country.field_id = 16 AND
users.user_id = interest.item_id AND
interest.value = interest_label.option_id AND
users.user_id = country.item_id AND
country.value = country_label.option_id AND
users.user_id = points.ref_id AND
users.user_id = ufs.item_id;
That produces:
array(size = 2)
0 =>
array(size = 8)
'email' => string 'info#mygreatsite.com'
'first_name' => string 'Filip'
'last_name' => string 'Moore'
'country' => string 'United Kingdom'
'interest' => string 'Fishing'
'actions' => string '53'
'badges' => string '4'
'points' => string '21.00'
1 =>
array(size = 8)
'email' => string 'user#mygreatsite.com'
'first_name' => string 'Peter'
'last_name' => string 'Smith'
'country' => string 'Spain'
'interest' => string 'Swimming'
'actions' => string '44'
'badges' => string '5'
'points' => string '212.00'
And here are the CREATE TABLE statements of all tables involved:
CREATE TABLE `site_users` (
`user_id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`email` varchar(128) COLLATE utf8_unicode_ci NOT NULL,
`username` varchar(128) COLLATE utf8_unicode_ci DEFAULT NULL,
`displayname` varchar(128) COLLATE utf8_unicode_ci NOT NULL DEFAULT '',
`photo_id` int(11) unsigned NOT NULL DEFAULT '0',
`password` char(32) COLLATE utf8_unicode_ci NOT NULL,
`salt` char(64) COLLATE utf8_unicode_ci NOT NULL,
`locale` varchar(16) CHARACTER SET latin1 COLLATE latin1_general_ci NOT NULL DEFAULT 'auto',
`language` varchar(8) CHARACTER SET latin1 COLLATE latin1_general_ci NOT NULL DEFAULT 'en_US',
`enabled` tinyint(1) NOT NULL DEFAULT '1',
`creation_date` datetime NOT NULL,
`modified_date` datetime NOT NULL,
PRIMARY KEY (`user_id`),
UNIQUE KEY `EMAIL` (`email`),
UNIQUE KEY `USERNAME` (`username`),
KEY `CREATION_DATE` (`creation_date`),
KEY `enabled` (`enabled`)
) ENGINE=InnoDB AUTO_INCREMENT=10 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
CREATE TABLE `site_user_fields_options` (
`option_id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`field_id` int(11) unsigned NOT NULL,
`label` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
`order` smallint(6) NOT NULL DEFAULT '999',
PRIMARY KEY (`option_id`),
KEY `field_id` (`field_id`)
) ENGINE=InnoDB AUTO_INCREMENT=14 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
CREATE TABLE `site_user_fields_values` (
`item_id` int(11) unsigned NOT NULL,
`field_id` int(11) unsigned NOT NULL,
`index` smallint(3) unsigned NOT NULL DEFAULT '0',
`value` text COLLATE utf8_unicode_ci NOT NULL,
`privacy` varchar(64) COLLATE utf8_unicode_ci DEFAULT NULL,
PRIMARY KEY (`item_id`,`field_id`,`index`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
CREATE TABLE `site_user_fields_search` (
`item_id` int(11) unsigned NOT NULL,
`profile_type` smallint(11) unsigned DEFAULT NULL,
`first_name` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
`last_name` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
`gender` smallint(6) unsigned DEFAULT NULL,
`birthdate` date DEFAULT NULL,
`field_15` enum('4','5','6','7','8','9','10') COLLATE utf8_unicode_ci DEFAULT NULL,
`field_16` enum('11','12','13') COLLATE utf8_unicode_ci DEFAULT NULL,
PRIMARY KEY (`item_id`),
KEY `profile_type` (`profile_type`),
KEY `first_name` (`first_name`),
KEY `last_name` (`last_name`),
KEY `gender` (`gender`),
KEY `birthdate` (`birthdate`),
KEY `field_15` (`field_15`),
KEY `field_16` (`field_16`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
CREATE TABLE IF NOT EXISTS `points_users` (
`user_id` int(11) unsigned NOT NULL auto_increment,
`ref_id` int(11) unsigned NOT NULL,
`actions` int(11) unsigned DEFAULT 0,
`badges` int(11) unsigned DEFAULT 0,
`points` FLOAT(12) unsigned DEFAULT 0,
`creation_date` DATETIME DEFAULT '00-00-00 00:00:00',
`modified_date` DATETIME DEFAULT '00-00-00 00:00:00',
PRIMARY KEY (`user_id`),
KEY `ref_id` (`ref_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
I would be very thankful for your help.
You already gave the right hint with LEFT JOIN yourself. So, it could be as easy as
SELECT
users.email,
ufs.first_name,
ufs.last_name,
country_label.label as country,
interest_label.label as interest,
points.actions,
points.badges,
points.points
FROM site_users users
LEFT JOIN site_user_fields_values interest ON users.user_id = interest.item_id
LEFT JOIN site_user_fields_options interest_label ON interest.value = interest_label.option_id
LEFT JOIN site_user_fields_values country ON users.user_id = country.item_id
LEFT JOIN site_user_fields_options country_label ON country.value = country_label.option_id
LEFT JOIN points_users points ON users.user_id = points.ref_id
LEFT JOIN site_user_fields_search ufs ON users.user_id = ufs.item_id
WHERE
interest.field_id = 15 AND
country.field_id = 16
;
Please note, however, it is currently unclear, whether this statement is really what you want (to LEFT JOIN in all cases). There might be cases, where an INNER JOIN is more appropriate. To check, we would need to discuss about foreign key relationship and/or have the CREATE TABLE statements of all the tables involved.

MySQL - SAME query with one variabile change take more then 10x longer

I have MySQL DB where I always ask same "question", only thing I change is VIN variabile in query.
To be more specific I show you 2 querys:
Firsth one with VIN: U5YFF24128L064909 (takes 0.0002 sec)
SELECT c.vin, c.case_id, c.claimnumber, c.platenumber, c.axrmrs_id,
c.insurer_memberid, c.country, c.date_created, c.totalloss,
c.lastcalc_manufacturer_code, c.lastcalc_model_code, c.lastcalc_submodel_code,
c.audavin_triggered, c.accident_date, c.registration_date,
c.manufacturing_year, cl.spareparts, cl.totalcosts, cl.laborhours,
cl.laborcosts, cl.calculationdate, cl.paintlabor, cl.paintmaterial,
cl.currency, car.manufacturer, car.model, car.submodel,
IFNULL(org.name, 0) as orgName, GROUP_CONCAT(DISTINCT IF(po.repairmethod LIKE 'L%',
po.text,NULL)
ORDER BY 1) AS textL, GROUP_CONCAT(DISTINCT IF(po.repairmethod = 'E',
po.text,NULL
)
ORDER BY 1) AS textE , GROUP_CONCAT(DISTINCT IF(po.repairmethod != 'E'
OR (po.repairmethod = 'E'
AND po.guidenumber = 'N/A'
)
AND po.repairmethod NOT LIKE 'L%',po.text, NULL
)
ORDER BY 1
) AS textO
FROM axnmrs_cases AS c
LEFT JOIN axnmrs_calculations as cl on c.case_id = cl.case_id
AND c.country = cl.country
LEFT JOIN axnmrs_positions as po on c.case_id = po.case_id
LEFT JOIN car_type as car on car.manufacturer_code = c.lastcalc_manufacturer_code
AND car.main_type = c.lastcalc_model_code
AND car.subtype_code = c.lastcalc_submodel_code
LEFT JOIN organization_list as org on org.memberId = c.insurer_memberid
WHERE c.vin= 'U5YFF24128L064909'
GROUP BY c.vin, c.case_id, c.axrmrs_id
And SECOND one with VIN = VF38BRHZE80728805 (this takes 2.4387 sec)
SELECT c.vin, c.case_id, c.claimnumber, c.platenumber, c.axrmrs_id,
c.insurer_memberid, c.country, c.date_created, c.totalloss,
c.lastcalc_manufacturer_code, c.lastcalc_model_code, c.lastcalc_submodel_code,
c.audavin_triggered, c.accident_date, c.registration_date,
c.manufacturing_year, cl.spareparts, cl.totalcosts, cl.laborhours,
cl.laborcosts, cl.calculationdate, cl.paintlabor, cl.paintmaterial,
cl.currency, car.manufacturer, car.model, car.submodel,
IFNULL(org.name, 0) as orgName, GROUP_CONCAT(DISTINCT IF(po.repairmethod LIKE 'L%',
po.text,NULL)
ORDER BY 1) AS textL, GROUP_CONCAT(DISTINCT IF(po.repairmethod = 'E',
po.text,NULL
)
ORDER BY 1) AS textE , GROUP_CONCAT(DISTINCT IF(po.repairmethod != 'E'
OR (po.repairmethod = 'E'
AND po.guidenumber = 'N/A'
)
AND po.repairmethod NOT LIKE 'L%',po.text, NULL
)
ORDER BY 1
) AS textO
FROM axnmrs_cases AS c
LEFT JOIN axnmrs_calculations as cl on c.case_id = cl.case_id
AND c.country = cl.country
LEFT JOIN axnmrs_positions as po on c.case_id = po.case_id
LEFT JOIN car_type as car on car.manufacturer_code = c.lastcalc_manufacturer_code
AND car.main_type = c.lastcalc_model_code
AND car.subtype_code = c.lastcalc_submodel_code
LEFT JOIN organization_list as org on org.memberId = c.insurer_memberid
WHERE c.vin= 'VF38BRHZE80728805'
GROUP BY c.vin, c.case_id, c.axrmrs_id
I have no clue why this happen so I try to analyze so i use "PROFILE" function in PHPMYADMIN which return me result as below on screens:
VIN: U5YFF24128L064909
And VIN: VF38BRHZE80728805 (it is obviously longer operation )
Becuase i wasnt able to google anything usefull from this I also try EXPLAIN SELECT query which looks like this:
For VIN: U5YFF24128L064909
And for VIN: VF38BRHZE80728805
From this explain I think I'm doing bad query on car_type table which should be written better, however it will not change speed of same query just with different VIN number.
I was also thinking that my first QUERY just return from CACHE and second come from DB. So i try to do both query again. And both again take same time as before.
Is here anyone who can help me find what's the issue of this query? What I'm doing wrong?
Thank you for any advise because I am lost in this already!
EDIT:
In car_type table I have indexes on: manufacturer_code, main_type, subtype_code
EDIT2:
To analyze deeper I try to SHOW CREATE TABLE {{table name}} and results are below.
axnmrs_cases:
CREATE TABLE `axnmrs_cases` (
`axrmrs_id` int(11) NOT NULL DEFAULT '0',
`case_id` int(11) NOT NULL DEFAULT '0',
`axncase_guid` varchar(100) COLLATE utf8_unicode_ci NOT NULL DEFAULT '0',
`date_created` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
`datasource` varchar(10) COLLATE utf8_unicode_ci NOT NULL DEFAULT '0',
`claimnumber` varchar(60) COLLATE utf8_unicode_ci NOT NULL DEFAULT '0',
`platenumber` varchar(60) COLLATE utf8_unicode_ci NOT NULL DEFAULT '0',
`displayname` varchar(200) COLLATE utf8_unicode_ci NOT NULL DEFAULT '0',
`vin` varchar(40) COLLATE utf8_unicode_ci NOT NULL DEFAULT '0',
`lastcalc_manufacturer_code` varchar(2) COLLATE utf8_unicode_ci NOT NULL DEFAULT '0',
`lastcalc_model_code` varchar(2) COLLATE utf8_unicode_ci NOT NULL DEFAULT '0',
`lastcalc_submodel_code` varchar(2) COLLATE utf8_unicode_ci NOT NULL DEFAULT '0',
`lastcalc_model_options` varchar(500) COLLATE utf8_unicode_ci NOT NULL DEFAULT '0',
`audavin_triggered` varchar(1) COLLATE utf8_unicode_ci NOT NULL DEFAULT '0',
`vehicletype` varchar(1) COLLATE utf8_unicode_ci NOT NULL DEFAULT '0',
`accident_date` timestamp NULL DEFAULT '0000-00-00 00:00:00',
`date_closed` timestamp NULL DEFAULT '0000-00-00 00:00:00',
`claimowner_memberid` varchar(200) COLLATE utf8_unicode_ci NOT NULL DEFAULT '0',
`repairer_memberid` varchar(200) COLLATE utf8_unicode_ci NOT NULL DEFAULT '0',
`insurer_memberid` varchar(200) COLLATE utf8_unicode_ci NOT NULL DEFAULT '0',
`assessor_memberid` varchar(200) COLLATE utf8_unicode_ci NOT NULL DEFAULT '0',
`accidentcause_code` int(11) DEFAULT NULL,
`casetype_code` int(11) DEFAULT NULL,
`claimtype_code` int(11) DEFAULT NULL,
`damagecause_code` int(11) DEFAULT NULL,
`damagearea_codes` varchar(20) COLLATE utf8_unicode_ci NOT NULL DEFAULT '0',
`totalloss` varchar(1) COLLATE utf8_unicode_ci NOT NULL DEFAULT '0',
`inspectionrequired` varchar(1) COLLATE utf8_unicode_ci NOT NULL DEFAULT '0',
`manufacturing_year` int(11) NOT NULL DEFAULT '0',
`registration_date` timestamp NULL DEFAULT '0000-00-00 00:00:00',
`mileage` int(11) NOT NULL DEFAULT '0',
`country` varchar(2) COLLATE utf8_unicode_ci NOT NULL DEFAULT '0',
`id` int(11) NOT NULL AUTO_INCREMENT,
PRIMARY KEY (`id`),
KEY `VIN_index` (`vin`)
) ENGINE=InnoDB AUTO_INCREMENT=3471525 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci
axnmrs_calculations:
CREATE TABLE `axnmrs_calculations` (
`calculation_id` int(11) NOT NULL,
`case_id` int(11) NOT NULL,
`guid` varchar(50) NOT NULL,
`calculationdate` varchar(50) NOT NULL,
`name` varchar(50) NOT NULL,
`calsscalnr` varchar(50) NOT NULL,
`model_options` varchar(60) NOT NULL,
`spareparts` varchar(60) NOT NULL,
`laborcosts` varchar(60) NOT NULL,
`paintlabor` varchar(60) NOT NULL,
`paintmaterial` varchar(40) NOT NULL,
`extracosts` varchar(60) NOT NULL,
`environmentalcosts` varchar(60) NOT NULL,
`totalcosts` varchar(60) NOT NULL,
`totalvat` varchar(60) NOT NULL,
`laborhours` varchar(60) NOT NULL,
`painthours` varchar(60) NOT NULL,
`totaldeduction` varchar(60) NOT NULL,
`partsadjustment` varchar(60) NOT NULL,
`calculationtype` varchar(60) NOT NULL,
`license` varchar(60) NOT NULL,
`memberrole` varchar(60) NOT NULL,
`currency` varchar(5) NOT NULL,
`country` varchar(2) NOT NULL,
KEY `caseid_index` (`case_id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1
axnmrs_positions:
CREATE TABLE `axnmrs_positions` (
`calculation_id` int(11) NOT NULL DEFAULT '0',
`case_id` int(11) NOT NULL DEFAULT '0',
`position_id` int(11) NOT NULL DEFAULT '0',
`blockline` varchar(7) COLLATE utf8_unicode_ci NOT NULL DEFAULT '0',
`repairmethod` varchar(3) COLLATE utf8_unicode_ci NOT NULL DEFAULT '0',
`guidenumber` varchar(4) COLLATE utf8_unicode_ci NOT NULL DEFAULT '0',
`amount` float NOT NULL DEFAULT '0',
`hours` float NOT NULL DEFAULT '0',
`starmutation` varchar(1) COLLATE utf8_unicode_ci NOT NULL DEFAULT '0',
`text` varchar(200) COLLATE utf8_unicode_ci NOT NULL DEFAULT '0',
`originalpartnumber` varchar(50) COLLATE utf8_unicode_ci NOT NULL DEFAULT '0',
`originalpartprice` float NOT NULL DEFAULT '0',
`manufacturercode` varchar(10) COLLATE utf8_unicode_ci NOT NULL DEFAULT '0',
`quality` varchar(5) COLLATE utf8_unicode_ci NOT NULL DEFAULT '0',
`suppliercode` varchar(10) COLLATE utf8_unicode_ci NOT NULL DEFAULT '0',
KEY `calculationid_index` (`calculation_id`),
KEY `repairmethod` (`repairmethod`),
KEY `caseid_index` (`case_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci
car_type:
CREATE TABLE `car_type` (
`manufacturer_code` varchar(2) NOT NULL,
`main_type` varchar(2) NOT NULL,
`subtype_code` varchar(2) NOT NULL,
`manufacturer` varchar(100) NOT NULL,
`model` varchar(20) CHARACTER SET utf8 COLLATE utf8_czech_ci NOT NULL,
`submodel` varchar(20) CHARACTER SET utf8 COLLATE utf8_czech_ci NOT NULL,
KEY `manufacturer_code` (`manufacturer_code`),
KEY `main_type` (`main_type`),
KEY `subtype_code` (`subtype_code`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1
organization_list:
CREATE TABLE `organization_list` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`memberId` varchar(99) NOT NULL,
`name` varchar(100) CHARACTER SET utf8 COLLATE utf8_czech_ci NOT NULL,
PRIMARY KEY (`id`),
KEY `memberId` (`memberId`)
) ENGINE=InnoDB AUTO_INCREMENT=133 DEFAULT CHARSET=latin1
The profile gives you the answer -- the Query cache.
The only way to get a result from a query like that in only 0.2 is for it to be coming from the "Query cache". This is a hash of selects to resultsets. You apparently ran the query twice and this was the second timing. Try again with SELECT SQL_NO_CACHE ... to see how long it "really" takes.
Please note that the "Query cache" is not the only "cache" that MySQL uses; so be careful in using the terminology.
(And that's not 10x; that's 10000x longer.)
That aside, your next question will be Why does such a query take 2.4 seconds? That is the question that you should address. The clues are in the EXPLAIN -- First notice the huge "rows" for car.
LEFT JOIN car_type as car
on car.manufacturer_code = c.lastcalc_manufacturer_code
AND car.main_type = c.lastcalc_model_code
AND car.subtype_code = c.lastcalc_submodel_code
Adding this composite index to car_type will speed up that part of the query.
INDEX(manufacturer_code, main_type, subtype_code)
(The order does not matter in this case.)
Also,
LEFT JOIN organization_list as org on org.memberId = c.insurer_memberid
needs a consistent definition for memberId. Look carefully at the CHARACTER SET in the two tables.
Use ALTER TABLE ... CONVERT TO ... to fix this issue so that it can use the index.
See also Index Cookbook
It looks like your first result was stored and therefore retrieved from the "Query cache". Looking at the profile on 2. Almost all the time is spent writing the result to a table in order to cache the result.
Try checking the direct disk IO graph on the DB if you can

limit in mysql with 10K record taking too much time to execute(fail every time)

I am using MySQL database. I have a table that consist up to 75K rows of data. I am using simple query to fetch data:
select * from mytable
It works fine, shows 75k rows in few seconds. I wanted to fetch some of these data I had used limit 10000. It got stuck every time. I need to optimize MySQL query for 10k records.
I am using query like this:
select * from mytable limit 10000
Give me some solution how to execute my query fast.
my database structure is like that:
CREATE TABLE IF NOT EXISTS `mytable` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`col1` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
`col2` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
`col3` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
`col4` varchar(255) COLLATE utf8_unicode_ci NOT NULL DEFAULT '',
`col5` int(11) NOT NULL,
`col6` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`col7` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
`col8` int(11) NOT NULL,
`col9` int(11) NOT NULL,
`col11` int(11) NOT NULL,
`col12` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
`col13` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
`col15` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
`col16` enum('0','1') COLLATE utf8_unicode_ci NOT NULL DEFAULT '0',
`col17` int(11) NOT NULL,
`col18` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
`col19` enum('0','1') COLLATE utf8_unicode_ci NOT NULL,
PRIMARY KEY (`id`),
KEY `id` (`id`,`col2`,`col3`,`col4`,`col5`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=75530 ;
With this solution I can fetch larger data in few seconds:
SELECT l.id,l.col1,l.col2,l.col3,l.col3,l.col4,l.col5,l.col6,l.col7
FROM (
SELECT id
FROM mytable
WHERE removed='0'
ORDER BY id
LIMIT 10000
) o
JOIN mytable ON l.id = o.id
ORDER BY l.id

How query with data functions in group by ca be optimized

i have a query as given below
SELECT MONTHNAME( f.receipt_date ) AS MONTH ,
SUM( CASE WHEN fm.fee_name = 'University Fees' THEN f.fee_amount END ) AS A
FROM fee_type_masters fm
INNER JOIN student_fee_collections f ON fm.id = f.fee_type
GROUP BY MONTH( f.receipt_date )
and my tables are like
CREATE TABLE `fee_type_masters` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`fee_name` varchar(255) DEFAULT NULL,
`fee_type` varchar(255) DEFAULT NULL,
`year` varchar(255) DEFAULT NULL,
`student_type` int(11) DEFAULT NULL,
`due_date` varchar(255) DEFAULT NULL,
`amount` float DEFAULT NULL,
`accounts_master_id` varchar(255) DEFAULT NULL,
`comments` varchar(255) DEFAULT NULL,
`status` varchar(255) DEFAULT NULL,
`sem` varchar(255) DEFAULT NULL,
`degree_id` int(11) DEFAULT NULL,
`approve_needed` varchar(255) DEFAULT NULL,
`concession_allowed` varchar(255) DEFAULT NULL,
`created_at` datetime DEFAULT NULL,
`updated_at` datetime DEFAULT NULL,
`relation_id` int(11) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=8 DEFAULT CHARSET=latin1
CREATE TABLE `student_fee_collections` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`student_id` int(11) DEFAULT NULL,
`fee_type` int(11) DEFAULT NULL,
`fee_amount` int(11) DEFAULT '0',
`due` int(11) DEFAULT '0',
`received` int(11) DEFAULT '0',
`concession` int(11) DEFAULT '0',
`receipt_no` int(11) DEFAULT NULL,
`receipt_date` date DEFAULT NULL,
`received_by` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
`amount` int(11) DEFAULT '0',
`late_fee` int(11) DEFAULT '0',
`pay_mode` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
`comments` text COLLATE utf8_unicode_ci,
`created_at` datetime DEFAULT NULL,
`updated_at` datetime DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `student_id` (`fee_type`,`student_id`)
) ENGINE=InnoDB AUTO_INCREMENT=325 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci
each is having more than 20000 rows
and my explain plan is like
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE fm ALL PRIMARY NULL NULL NULL 7000 Using temporary; Using filesort
1 SIMPLE f ref student_id student_id 5 emsnew.fm.id 28000 Using where
any one please tell me how to optimize the query or rewrite.
Create Index on fee_type column in student_fee_collections and recheck the output of Explain Query. And update the same in your question.
Create Index on fee_type column in student_fee_colle
and run the following query
SELECT MONTHNAME( f.receipt_date ) AS MONTH ,
SUM( CASE WHEN fm.fee_name = 'University Fees' THEN f.fee_amount END ) AS A
FROM fee_type_masters fm
INNER JOIN student_fee_collections f USE index(fee_type_IDX) ON fm.id = f.fee_type
GROUP BY MONTH( f.receipt_date )