mysql select query is very slow and uses filesort - mysql

I have one big problem in the slow query select
0.3054 sec
this the query
SELECT id, ar_name, en_name,product_id,havproduct, viewnum, uid,pin_to, sid, ssid,cid, close,date
FROM subject
where active = '1' and deleted = '0' and cid= '24'
order by id DESC
LIMIT 0,30
and when i use this
explain
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE subject ALL NULL NULL NULL NULL 230026 Using where; Using filesort
and this table create
CREATE TABLE `subject` (
`id` int(11) NOT NULL,
`cid` int(11) NOT NULL,
`did` int(11) NOT NULL,
`sid` int(11) NOT NULL,
`ssid` int(11) NOT NULL,
`product_id` int(11) NOT NULL DEFAULT '0',
`havproduct` int(11) NOT NULL DEFAULT '0',
`uid` int(11) NOT NULL,
`ar_name` varchar(500) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL,
`en_name` varchar(500) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL,
`close` int(11) NOT NULL DEFAULT '0',
`active` int(11) NOT NULL,
`date` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`viewnum` int(11) NOT NULL DEFAULT '1',
`pin_to` int(11) NOT NULL DEFAULT '0',
`deleted` int(11) NOT NULL,
`user_active` int(11) NOT NULL DEFAULT '1',
`dep_active` int(11) NOT NULL DEFAULT '1'
) ENGINE=MyISAM DEFAULT CHARSET=utf8
and the table have 200000 record or more from data

You have no keys on your data. For your particularly query, the best index is:
create index id_subject_4 on subject(active, deleted, cid, id)
By the way, you should only use single quotes for string and date constants. All the values in your query are integers, so remove the quotes:
SELECT id, ar_name, en_name,product_id,havproduct, viewnum, uid, pin_to, sid, ssid,cid, close,date
FROM subject
where active = 1 and deleted = 0 and cid = 24
order by id DESC
LIMIT 0, 30;

Related

Improve a query from Explain results

I have a complex query that is dynamically assembled based upon search criteria. However, in its simplest form, it is still very slow. The main table it runs against has ~10M records. I ran an explain against a 'base' query and the first row of the explain looks bad (at least to a novice dba like me). I have read a couple tutorials about EXPLAIN, but I still am unsure how to fix the query. So, the first row of the results seems to indicate the problem, but I don't know what to do with it. I couldn't make a composite key that long even if I wanted to and some of the field names in that possible_keys column are not even in the patients table. Any help will be greatly appreciated.
id,select_type,table,type,possible_keys,key,key_len,ref,rows,Extra
1,SIMPLE,patients,range,"PRIMARY,location,appt_date,status,radiologist,contract,lastname,paperwork,images_archived,hash,created,document_attached,all_images_archived,last_image_archived,modality,study_uid,company,second_access,firstname,report_delivered,ssn,order_entry_status,dob,tech,doctor,mobile_facility,accession,location_appt_date,location_created,location_lastname,ref,person_seq",location_appt_date,55,NULL,573534,"Using index condition; Using where; Using temporary; Using filesort"
1,SIMPLE,receivable_transactions,ref,patient_seq,patient_seq,4,ris-dev.patients.seq,1,NULL
1,SIMPLE,patients_dispatch,ref,patient_seq,patient_seq,4,ris-dev.patients.seq,1,NULL
1,SIMPLE,mobile_facility,ref,"unique_index,name,location",unique_index,115,"ris-dev.patients.mobile_facility,const",1,"Using where"
1,SIMPLE,mobile_facility_service_areas,eq_ref,PRIMARY,PRIMARY,4,ris-dev.mobile_facility.service_area,1,NULL
Edit: same EXPLAIN, but reformatted to be easier to read:
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE patients range PRIMARY location_appt_date 55 NULL 573534 Using index condition; Using where; Using temporary; Using filesort
location
appt_date
status
radiologist
contract
lastname
paperwork
images_archived
hash
created
document_attached
all_images_archived
last_image_archived
modality
study_uid
company
second_access
firstname
report_delivered
ssn
order_entry_status
dob
tech
doctor
mobile_facility
accession
location_appt_date
location_created
location_lastname
ref
person_seq
1 SIMPLE receivable_transactions ref patient_seq patient_seq 4 ris-dev.patients.seq 1 NULL
1 SIMPLE patients_dispatch ref patient_seq patient_seq 4 ris-dev.patients.seq 1 NULL
1 SIMPLE mobile_facility ref unique_index unique_index 115 ris-dev.patients.mobile_facility,const 1 Using where
name
location
1 SIMPLE mobile_facility_service_areas eq_ref PRIMARY PRIMARY 4 ris-dev.mobile_facility.service_area 1 NULL
The explain is setup against the following query and table structures.
SELECT patients.fax_in_queue, patients.modality, patients.stat, patients.created, patients.seq, patients.lastname,
patients.firstname, patients.appt_date, patients.status, patients.contract, patients.location, patients.unique_hash,
patients.images_archived, patients.report_delivered, patients.doctor, patients.mobile_facility, patients.history,
patients.dob, patients.all_images_archived, patients.order_entry_status, patients.tech, patients.radiologist,
patients.last_image_archived, patients.state, patients.ss_comments, patients.completed, patients.report_status,
patients.have_paperwork, patients.facility_room_number, patients.facility_station_name, patients.facility_bed,
patients.findings_level, patients.document_attached, patients.study_start, patients.company, patients.accession,
patients.number_images, patients.client_number_images, patients.sex, patients.threshhold , GROUP_CONCAT(CONCAT(CONCAT(receivable_transactions.modifier, " "),
receivable_transactions.description) SEPARATOR ", ") AS rt_desc , patients_dispatch.seq AS doc_seq, patients_dispatch.requisition_last_sent,
patients_dispatch.requisition_signed_by_file_seq, patients_dispatch.requisition_signed, patients_dispatch.order_reason, patients_dispatch.order_comments,
patients_dispatch.order_taken, patients_dispatch.order_tech_last_notified, patients_dispatch.order_tech_in_transit, patients_dispatch.order_tech_in,
patients_dispatch.order_tech_out, patients_dispatch.order_tech_ack, patients_dispatch.addr1 AS d_addr1, patients_dispatch.addr2 AS d_addr2,
patients_dispatch.city AS d_city, patients_dispatch.state AS d_state, patients_dispatch.zip AS d_zip, CONCAT(patients.status, order_tech_out,
order_tech_in, order_tech_in_transit) as pseudo_status , mobile_facility.requisition_fax, mobile_facility.station_list, mobile_facility.address1 as mf_addr1,
mobile_facility.address2 as mf_addr2, mobile_facility.city as mf_city, mobile_facility.state as mf_state, mobile_facility.zip as mf_zip,
mobile_facility.phone as mf_phone, mobile_facility.phone2 as mf_phone2, mobile_facility_service_areas.name as mf_service_area
FROM patients LEFT JOIN receivable_transactions ON patients.seq = receivable_transactions.patient_seq
LEFT JOIN patients_dispatch ON patients.seq = patients_dispatch.patient_seq
LEFT JOIN mobile_facility ON patients.location = mobile_facility.location AND patients.mobile_facility = mobile_facility.name
LEFT JOIN mobile_facility_service_areas ON mobile_facility.service_area = mobile_facility_service_areas.seq
WHERE patients.location = "XYZCompany" AND ((patients.appt_date >= '2020-03-19' AND patients.appt_date <= '2020-03-19 23:59:59')
OR (patients.appt_date <= '2020-03-19' AND patients.status < 'X'))
GROUP BY patients.seq DESC
ORDER BY patients.status, patients.order_entry_status, pseudo_status, patients.order_entry_status,patients.lastname);
CREATE TABLE `patients` (
`seq` int(11) NOT NULL AUTO_INCREMENT,
`person_seq` int(11) NOT NULL,
`firstname` varchar(20) NOT NULL DEFAULT '',
`lastname` varchar(30) NOT NULL DEFAULT '',
`middlename` varchar(20) NOT NULL DEFAULT '',
`ref` varchar(50) NOT NULL DEFAULT '',
`location` varchar(50) NOT NULL DEFAULT '',
`doctor` varchar(50) NOT NULL,
`radiologist` varchar(20) NOT NULL DEFAULT '',
`contract` varchar(50) NOT NULL,
`history` mediumtext NOT NULL,
`dob` varchar(15) NOT NULL DEFAULT '0000-00-00',
`appt_date` date NOT NULL DEFAULT '0000-00-00',
`status` tinyint(4) NOT NULL DEFAULT '0',
`tech` varchar(50) NOT NULL DEFAULT '',
`created` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
`ss_comments` mediumtext NOT NULL,
`mobile_facility` varchar(60) NOT NULL DEFAULT '',
`facility_room_number` varchar(50) NOT NULL,
`facility_bed` varchar(20) NOT NULL,
`facility_station_name` varchar(50) NOT NULL,
`stat` tinyint(4) NOT NULL DEFAULT '0',
`have_paperwork` tinyint(4) NOT NULL DEFAULT '0',
`completed` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
`sex` char(1) NOT NULL DEFAULT '',
`unique_hash` varchar(100) NOT NULL DEFAULT '',
`number_images` int(11) NOT NULL DEFAULT '0',
`client_number_images` int(11) NOT NULL,
`images_archived` tinyint(4) NOT NULL DEFAULT '0',
`completed_fax` varchar(10) NOT NULL DEFAULT '0' COMMENT 'This is the number the completed report is faxed to.',
`report_delivered` tinyint(4) NOT NULL DEFAULT '0',
`report_delivered_time` datetime NOT NULL,
`document_attached` tinyint(4) NOT NULL DEFAULT '0',
`modality` varchar(3) NOT NULL,
`last_image_archived` datetime NOT NULL,
`all_images_archived` tinyint(4) NOT NULL DEFAULT '0',
`fax_in_queue` varchar(12) NOT NULL,
`accession` varchar(100) NOT NULL,
`study_uid` varchar(100) NOT NULL,
`order_entry_status` tinyint(4) NOT NULL,
`compare_to` varchar(15) NOT NULL,
`state` varchar(3) NOT NULL,
`company` int(11) NOT NULL,
`second_access` varchar(50) NOT NULL,
`threshhold` datetime NOT NULL,
`report_status` tinyint(4) NOT NULL,
`second_id` varchar(50) NOT NULL,
`rad_alerted` tinyint(4) NOT NULL,
`assigned` datetime NOT NULL,
`findings_level` tinyint(4) NOT NULL,
`report_viewed` tinyint(4) NOT NULL,
`study_received` datetime NOT NULL,
`study_start` datetime NOT NULL,
`study_end` datetime NOT NULL,
`completed_email` varchar(50) NOT NULL,
`completed_send` varchar(255) NOT NULL,
`ssn` varchar(12) NOT NULL,
`exorder_number` varchar(30) NOT NULL,
`exvisit_number` varchar(30) NOT NULL,
`row_updated` timestamp NOT NULL ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`seq`),
KEY `location` (`location`),
KEY `appt_date` (`appt_date`),
KEY `status` (`status`),
KEY `radiologist` (`radiologist`),
KEY `contract` (`contract`),
KEY `lastname` (`lastname`),
KEY `paperwork` (`have_paperwork`),
KEY `images_archived` (`images_archived`),
KEY `hash` (`unique_hash`),
KEY `created` (`created`),
KEY `document_attached` (`document_attached`),
KEY `all_images_archived` (`all_images_archived`),
KEY `last_image_archived` (`last_image_archived`),
KEY `modality` (`modality`),
KEY `study_uid` (`study_uid`),
KEY `company` (`company`),
KEY `second_access` (`second_access`),
KEY `firstname` (`firstname`),
KEY `report_delivered` (`report_delivered`),
KEY `ssn` (`ssn`),
KEY `order_entry_status` (`order_entry_status`),
KEY `dob` (`dob`),
KEY `tech` (`tech`),
KEY `doctor` (`doctor`),
KEY `mobile_facility` (`mobile_facility`),
KEY `accession` (`accession`),
KEY `location_appt_date` (`location`,`appt_date`),
KEY `location_created` (`location`,`created`),
KEY `location_lastname` (`location`,`lastname`),
KEY `ref` (`ref`),
KEY `person_seq` (`person_seq`)
) ENGINE=InnoDB AUTO_INCREMENT=10242952 DEFAULT CHARSET=latin1;
CREATE TABLE `receivable_transactions` (
`seq` int(11) NOT NULL AUTO_INCREMENT,
`patient_seq` int(11) NOT NULL DEFAULT '0',
`cptcode` varchar(15) NOT NULL DEFAULT '',
`modifier` char(2) NOT NULL DEFAULT '',
`description` varchar(100) NOT NULL DEFAULT '',
`amount` decimal(6,2) NOT NULL DEFAULT '0.00',
`type` char(2) NOT NULL DEFAULT '',
`transaction` varchar(10) NOT NULL DEFAULT '',
`radiologist` varchar(20) NOT NULL DEFAULT '',
`status` tinyint(4) NOT NULL DEFAULT '0',
`completed` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
`created` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
`report_meta_seq` int(11) NOT NULL DEFAULT '0',
`report_header` varchar(255) NOT NULL,
`report_body` blob NOT NULL,
`report_impression` mediumtext NOT NULL,
`report_hide` tinyint(4) NOT NULL,
`radiologist_group` varchar(50) NOT NULL,
`addendum` int(4) NOT NULL DEFAULT '0',
`addendum_type` varchar(20) NOT NULL,
`peer_review` int(4) NOT NULL DEFAULT '0',
`qa_reason` varchar(255) NOT NULL DEFAULT '',
`qa_agree` decimal(2,1) NOT NULL DEFAULT '0.0',
`findings` tinyint(4) NOT NULL,
`comments` mediumtext NOT NULL,
`company` int(11) NOT NULL,
`row_updated` timestamp NOT NULL ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`seq`),
KEY `patient_seq` (`patient_seq`),
KEY `cptcode` (`cptcode`),
KEY `transaction` (`transaction`),
KEY `type` (`type`),
KEY `created` (`created`),
KEY `radiologist` (`radiologist`),
KEY `status` (`status`),
KEY `report_meta_seq` (`report_meta_seq`),
KEY `Billing Check Dropdown` (`status`,`completed`),
KEY `qa_agree` (`qa_agree`),
KEY `peer_review` (`peer_review`),
KEY `addendum` (`addendum`),
KEY `company` (`company`),
KEY `completed` (`completed`)
) ENGINE=InnoDB AUTO_INCREMENT=9380351 DEFAULT CHARSET=latin1;
CREATE TABLE `patients_dispatch` (
`seq` int(11) NOT NULL AUTO_INCREMENT,
`patient_seq` int(11) NOT NULL,
`order_taken` datetime NOT NULL,
`order_taken_by` varchar(50) NOT NULL,
`order_person_calling` varchar(50) NOT NULL,
`order_supervising_physician` varchar(50) NOT NULL,
`order_trip_count` tinyint(4) NOT NULL,
`order_trip_count_max` tinyint(4) NOT NULL,
`order_trip_visit` tinyint(4) NOT NULL,
`order_tech_in` datetime NOT NULL,
`order_tech_out` datetime NOT NULL,
`order_ssn` varchar(12) NOT NULL,
`order_service_request_time` datetime NOT NULL,
`order_reason` varchar(255) NOT NULL,
`order_tech_ack` datetime NOT NULL,
`order_tech_assigned` datetime NOT NULL,
`order_tech_last_notified` datetime NOT NULL,
`requisition_last_sent` datetime NOT NULL,
`requisition_signed` datetime NOT NULL,
`requisition_signed_by` varchar(50) NOT NULL,
`requisition_signed_by_text` varchar(75) NOT NULL,
`requisition_signed_by_file_seq` int(11) NOT NULL,
`order_comments` mediumtext NOT NULL,
`order_tech_in_transit` datetime NOT NULL,
`fasting` tinyint(1) NOT NULL,
`collection_time` time DEFAULT NULL,
`addr1` varchar(100) NOT NULL,
`addr2` varchar(100) NOT NULL,
`city` varchar(30) NOT NULL,
`state` varchar(3) NOT NULL,
`zip` varchar(12) NOT NULL,
`phone` varchar(15) NOT NULL,
`mileage_start` int(11) NOT NULL,
`mileage_end` int(11) NOT NULL,
PRIMARY KEY (`seq`),
KEY `patient_seq` (`patient_seq`)
) ENGINE=InnoDB AUTO_INCREMENT=2261091 DEFAULT CHARSET=latin1;
CREATE TABLE `mobile_facility` (
`seq` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(60) NOT NULL,
`location` varchar(50) DEFAULT NULL,
`address1` varchar(50) NOT NULL,
`address2` varchar(50) NOT NULL,
`city` varchar(50) NOT NULL,
`state` varchar(2) NOT NULL,
`zip` varchar(10) NOT NULL,
`phone` varchar(15) NOT NULL,
`phone2` varchar(15) NOT NULL,
`fax` varchar(110) NOT NULL,
`rads_can_read` text NOT NULL,
`rads_cant_read` text NOT NULL,
`only_techs` text NOT NULL,
`never_modalities` varchar(255) NOT NULL COMMENT 'A serialized list of modalities a facility may not use.',
`station_list` mediumtext NOT NULL,
`email` varchar(255) NOT NULL,
`misc1` varchar(255) NOT NULL,
`latitude` float NOT NULL DEFAULT '0',
`longitude` float NOT NULL DEFAULT '0',
`affiliation` int(11) NOT NULL COMMENT 'mobile_facility_affiliations seq',
`branch` int(11) NOT NULL COMMENT 'mobile_facility_branches seq',
`service_area` int(11) NOT NULL COMMENT 'mobile_facility_service_areas seq',
`other_id` varchar(50) NOT NULL COMMENT 'Usually used for HL7',
`facility_type` varchar(2) DEFAULT NULL,
`no_stat` tinyint(1) NOT NULL DEFAULT '0' COMMENT 'Should the facility allow stat priority on patients?',
`facility_notes` varchar(512) DEFAULT NULL,
`requisition_fax` varchar(110) NOT NULL,
`report_template` text NOT NULL,
`all_orders_stat` tinyint(1) NOT NULL,
`sms_notification` varchar(15) NOT NULL,
`tat` varchar(10) NOT NULL,
`npi` varchar(15) NOT NULL,
`NMXR` tinyint(4) NOT NULL DEFAULT '0',
`billing_type` varchar(10) NOT NULL,
`salesman` varchar(75) NOT NULL,
`created_at` datetime NOT NULL,
`updated_at` datetime NOT NULL,
`default_bill_to` tinyint(4) NOT NULL DEFAULT '0',
PRIMARY KEY (`seq`),
UNIQUE KEY `unique_index` (`name`,`location`),
KEY `name` (`name`),
KEY `location` (`location`)
) ENGINE=InnoDB AUTO_INCREMENT=155104 DEFAULT CHARSET=latin1;
CREATE TABLE `mobile_facility_service_areas` (
`seq` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(50) NOT NULL,
`location` varchar(50) NOT NULL,
PRIMARY KEY (`seq`)
) ENGINE=InnoDB AUTO_INCREMENT=841 DEFAULT CHARSET=latin1;
It's only using the index on location, but that only narrows down the search to about a half a million rows. You'd like it to use an index to further narrow down by the appt_date.
However, the use of OR in your WHERE clause is causing a problem. It can't decide how to use the index.
Here's what I suggest:
Drop the index on location because it's redundant with the other indexes that have location as their first column.
Replace the index on location_appt_date with an index on location_appt_date_status.
ALTER TABLE patients
DROP KEY location,
DROP KEY location_appt_date,
ADD KEY location_appt_date_status (location, appt_date, status);
Refactor the query to use UNION instead of OR:
SELECT ... (all the columns you have) ...
FROM (
SELECT * FROM patients USE INDEX (location_appt_date_status)
WHERE location = 'XYZCompany' AND appt_date >= '2020-03-19' AND appt_date < '2020-03-20'
UNION
SELECT * FROM patients USE INDEX (location_appt_date_status)
WHERE location = 'XYZCompany' AND appt_date <= '2020-03-19' AND status < 'X'
) AS p
LEFT JOIN receivable_transactions FORCE INDEX (patient_seq)
ON p.seq = receivable_transactions.patient_seq
LEFT JOIN patients_dispatch FORCE INDEX (patient_seq)
ON p.seq = patients_dispatch.patient_seq
INNER JOIN mobile_facility FORCE INDEX (unique_index)
ON p.location = mobile_facility.location AND p.mobile_facility = mobile_facility.name
INNER JOIN mobile_facility_service_areas FORCE INDEX (PRIMARY)
ON mobile_facility.service_area = mobile_facility_service_areas.seq
GROUP BY p.seq
ORDER BY p.status, p.order_entry_status, pseudo_status, p.order_entry_status, p.lastname
You might not need all the USE INDEX() / FORCE INDEX() optimizer hints I used. I did those because I was testing with empty tables, and that can confuse the optimizer.
Let me focus on the part that affects optimization the most:
FROM patients AS p
LEFT JOIN receivable_transactions AS rt ON p.seq = rt.patient_seq
LEFT JOIN patients_dispatch AS pd ON p.seq = pd.patient_seq
LEFT JOIN mobile_facility AS mf ON p.location = mf.location
AND p.mobile_facility AS mf = mf.name
LEFT JOIN mobile_facility_service_areas AS sa ON mf.service_area = sa.seq
WHERE p.location = "XYZCompany"
AND ((p.appt_date >= '2020-03-19'
AND p.appt_date <= '2020-03-19 23:59:59')
OR (p.appt_date <= '2020-03-19'
AND p.status < 'X')
)
GROUP BY p.seq DESC
ORDER BY p.status, p.order_entry_status, pseudo_status, p.order_entry_status,
p.lastname);
The biggest issue is the OR. It often prevents most optimizations. The usual fix is to turn it into a UNION:
( SELECT ...
FROM .. JOIN ..
WHERE p.location = "XYZCompany"
AND p.appt_date >= '2020-03-19'
AND p.appt_date < '2020-03-19' + INTERVAL 1 DAY
...
)
UNION ALL
( SELECT ...
FROM .. JOIN ..
WHERE p.location = "XYZCompany"
AND p.appt_date <= '2020-03-19'
AND p.status < 'X'
...
)
Each select can benefit from this composite index on patients:
(location, appt_date, status)
The < 'X' is problematic because two ranges (appt_date and status) cannot both be used effectively. What are the possible values of status? If there is only one value before 'X', say 'M', then this would be much better: p.status = 'M' together with another index: (location, status, appt_date)
SELECT lots of stuff, then GROUP BY p.seq -- This is probably create strange results. (Search for ONLY_FULL_GROUP_BY for more discussion). It may be better to first get the patients.seq values (since that is all you are filtering on), then join to the other tables. This would eliminate the GROUP BY, or at least force you to deal with which row to fetch from each of the other tables.
range location_appt_date 55 573534 Using index condition; Using where; Using temporary; Using filesort -- says
55 = 2+50 (for varchar(50)) + 3 (for date) -- neither is NULL.
Based on the 55, I wonder if it is so well optimized that the OR->UNION is not needed.
"Using index condition" is internally called ICP (Index Condition Pushdown) if you want further understanding.
"Using filesort" may be an understatement -- There are probably two sorts, one for GROUP BY, one for ORDER BY. EXPLAIN FORMAT=JSON SELECT ... would make it clear. (And hence my hint that the GROUP BY should be avoided.
You have some redundant indexes (not relevant to much other than disk space): INDEX(a,b), INDEX(a) --> toss INDEX(a).
patients has an awful number of indexes.
The other tables seem to have adequate indexes for your query.

Slow query when use order by with limit 1

I have a table in mysql with over 80M records. In MYISAM engine.
When I run this query
SELECT id FROM mytable WHERE (key1=-5) AND key2=467476 ORDER BY id DESC LIMIT 1
query is slow and after 5 minutes I must kill query to release table.
But when i just increase limit size this query work successfully in 44ms
For example (I just increase limit size):
SELECT id FROM mytable WHERE (key1=-5) AND key2=467476 ORDER BY id DESC LIMIT 2
Now to solve this issue i try the following query and this work successfully (this is temporary solution)
SELECT id FROM (SELECT id FROM mytable WHERE (key1=-5) AND key2=467476 ORDER BY id DESC LIMIT 2) AS tbl ORDER BY id DESC LIMIT 1
Note
: id is primary and auto increment !
Update:
key1 ==> folder_id
key2 ==> userid
CREATE TABLE `bm60_mails` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`userid` int(11) NOT NULL DEFAULT '0',
`betreff` varchar(255) CHARACTER SET utf8 NOT NULL,
`von` varchar(255) CHARACTER SET utf8 NOT NULL,
`an` varchar(255) CHARACTER SET utf8 NOT NULL,
`cc` varchar(255) CHARACTER SET utf8 NOT NULL,
`body` longtext NOT NULL,
`folder` int(11) NOT NULL,
`datum` int(11) NOT NULL DEFAULT '0',
`trashstamp` int(11) NOT NULL,
`priority` enum('low','normal','high') NOT NULL,
`fetched` int(11) NOT NULL DEFAULT '0',
`msg_id` varchar(128) CHARACTER SET utf8 NOT NULL,
`virnam` varchar(128) CHARACTER SET utf8 NOT NULL,
`trained` tinyint(4) NOT NULL DEFAULT '0',
`refs` text CHARACTER SET utf8 NOT NULL,
`flags` int(11) NOT NULL DEFAULT '-1',
`size` int(11) NOT NULL,
`color` tinyint(4) NOT NULL DEFAULT '0',
PRIMARY KEY (`id`),
KEY `mailUser` (`userid`),
KEY `mailFlags` (`flags`),
KEY `mailFolder` (`folder`)
) ENGINE=MyISAM AUTO_INCREMENT=95953499 DEFAULT CHARSET=latin1
I suspect if you create a compound index on (key1, key2, id) your problem will vanish.
The id column is also included because that's not implicit in MyISAM tables, althought it is in InnoDB tables.

MySQL Query Slows Dramatically With Order BY included

I know this has been addressed, but the solutions have not helped me.
I have a table with 3 million records. The columns are indexed.
SELECT * FROM checklist_search WHERE player LIKE '%Mike%' AND player LIKE '%Trout%'
ORDER BY 0+year ASC, search_data ASC, 0+cardnumber ASC
LIMIT 0, 50
Without the ORDER BY the query is fast - Query took 0.0156 sec
With the ORDER BY Query took 3.7068 sec
Based on other answers to this problem I tried
SELECT * FROM(SELECT * FROM checklist_search WHERE player LIKE '%Mike%' AND player LIKE '%Trout%'
) as myalias ORDER BY 0+year ASC, search_data ASC, 0+cardnumber ASC
LIMIT 0, 50
But the results are the same.
Here is the table and index structure
CREATE TABLE IF NOT EXISTS `checklist_search` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`page_type` varchar(10) NOT NULL DEFAULT '',
`checklist_db` varchar(20) NOT NULL DEFAULT '',
`set_id` int(10) unsigned NOT NULL,
`card_id` int(11) NOT NULL,
`search_data` varchar(255) NOT NULL DEFAULT '0',
`year` varchar(10) NOT NULL DEFAULT '0',
`brand` varchar(100) NOT NULL,
`issue` varchar(100) NOT NULL,
`set_name` varchar(150) NOT NULL DEFAULT '',
`cardnumber` varchar(10) NOT NULL,
`player` varchar(150) NOT NULL DEFAULT '',
`team` varchar(150) NOT NULL DEFAULT '',
`rc` int(1) NOT NULL,
`sp` int(1) NOT NULL,
`gu` int(1) NOT NULL,
`auto` int(1) NOT NULL,
`parallel` int(1) NOT NULL,
`insert_card` int(1) NOT NULL,
`card_count` int(10) NOT NULL,
`image_count` int(10) NOT NULL,
`print_run` varchar(20) NOT NULL,
`display_image_front` varchar(120) NOT NULL,
`display_image_back` varchar(120) NOT NULL,
`seo_url` varchar(255) NOT NULL,
`created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
KEY `card_id` (`card_id`),
KEY `checklist_db` (`checklist_db`),
KEY `year` (`year`),
KEY `player` (`player`),
KEY `team` (`team`),
KEY `print_run` (`print_run`),
KEY `rc` (`rc`),
KEY `set_id` (`set_id`),
KEY `search_data` (`search_data`),
KEY `cardnumber` (`cardnumber`),
FULLTEXT KEY `player_2` (`player`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 PACK_KEYS=0 AUTO_INCREMENT=3203103 ;
Any ideas would be greatly appreciated.
Thanks
Mike
EDIT: Here is the result for
EXPLAIN SELECT *
FROM checklist_search
WHERE player LIKE '%Mike%'
AND player LIKE '%Trout%'
ORDER BY year ASC , search_data ASC , cardnumber ASC
LIMIT 0 , 50
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE checklist_search ALL NULL NULL NULL NULL 2837591 Using where; Using filesort

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.

Mysql doesn't use my Index correctly

First sorry, i am french and i don't speak very well english.
I have a rather strange problem with my index.
my table t_bloc (my table contains all the posts)
t_bloc
CREATE TABLE `t_bloc` (
 `id_bloc` int(10) unsigned NOT NULL AUTO_INCREMENT,
 `id_rubrique` int(10) unsigned NOT NULL DEFAULT '0',
 `titre` varchar(100) NOT NULL DEFAULT 'A compléter',
 `contenu` text NOT NULL,
 `titre_page` varchar(100) NOT NULL,
 `desc_courte` varchar(255) NOT NULL,
 `url` varchar(255) NOT NULL,
 `follow_url` tinyint(1) unsigned NOT NULL DEFAULT '1' ,
 `image` varchar(120) NOT NULL,
 `video` varchar(120) NOT NULL,
 `note` tinyint(3) unsigned NOT NULL DEFAULT '0',
 `champopt1` text NOT NULL,
 `champopt2` text NOT NULL,
 `permalien` varchar(100) NOT NULL,
 `en_ligne` tinyint(1) NOT NULL DEFAULT '0',
 `id_utilisateur` int(10) unsigned NOT NULL DEFAULT '1' ,
 `date_crea` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
 `date_modif` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
 `nb_commentaires` smallint(5) unsigned NOT NULL DEFAULT '0',
 `nb_jaimes` int(10) unsigned NOT NULL DEFAULT '0',
 `nb_jaimespas` int(10) unsigned NOT NULL DEFAULT '0',
 `pourcentage_jaimes` smallint(2) unsigned NOT NULL DEFAULT '0' ,
 `niveau_classement` tinyint(1) unsigned NOT NULL DEFAULT '1' ,
 `id_bloc_parent` int(10) unsigned NOT NULL DEFAULT '0' ,
 `id_membre_bloc` int(10) unsigned NOT NULL DEFAULT '0' ,
 `valeur_pts_bloc` smallint(5) unsigned NOT NULL DEFAULT '0' ,
 `commentaires_actifs` tinyint(1) unsigned NOT NULL DEFAULT '1' ,
 PRIMARY KEY (`id_bloc`),
 KEY `date_modif` (`date_modif`),
 KEY `id_bloc_parent` (`id_bloc_parent`),
 KEY `idx_rub_ligne_niv_etc` (`id_rubrique`,`en_ligne`,`niveau_classement`,`note`,`pourcentage_jaimes`,`date_modif`),
 KEY `idx_tri` (`en_ligne`,`niveau_classement`,`note`,`pourcentage_jaimes`,`date_modif`),
 KEY `idx_ligne_membre` (`en_ligne`,`id_membre_bloc`,`id_rubrique`),
 KEY `id_membre_bloc` (`id_membre_bloc`),
 KEY `idx_rub_ligne_date` (`id_rubrique`,`en_ligne`,`date_modif`,`id_bloc`),
 KEY `idx_ligne_date` (`en_ligne`,`date_modif`),
 FULLTEXT KEY `idx_fullindex` (`titre`,`contenu`)
) ENGINE=MyISAM AUTO_INCREMENT=456469 DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC
My table t_taxon_bloc
t_taxon_bloc
CREATE TABLE `t_taxon_bloc` (
 `id_taxon` int(10) unsigned NOT NULL,
 `id_bloc` int(10) unsigned NOT NULL,
 `url_plateforme` varchar(255) NOT NULL,
 `width_flash` smallint(5) unsigned NOT NULL,
 `height_flash` smallint(5) unsigned NOT NULL,
 PRIMARY KEY (`id_taxon`,`id_bloc`),
 KEY `id_bloc` (`id_bloc`),
 KEY `id_taxon` (`id_taxon`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC
I have a problem when I execute this query:
select b.id_bloc FROM t_bloc as b WHERE b.en_ligne = 1 AND EXISTS ( SELECT 1 FROM t_taxon_bloc AS TB WHERE TB.id_bloc=B.id_bloc AND TB.id_taxon= 83) ORDER BY b.en_ligne DESC, b.date_modif DESC LIMIT 0, 20
I get the following explain:
id
select_type
table
type
possible_keys
key
key_len
ref
rows
Extra
1
PRIMARY
b
ref
idx_tri,idx_ligne_membre,idx_ligne_date
idx_ligne_date
1
const
58210
Using where
2
DEPENDENT SUBQUERY
TB
eq_ref
PRIMARY,id_bloc,id_taxon
PRIMARY
8
const,sitajeuxtestbourrage.b.id_bloc
1
Using index
it does not fully use the idx_ligne_date index and rows = all rows in the table
Extra = « using Where »
But if I create the following index idx_ligne_date_idbloc (en_ligne, date_modif, id_bloc) ,
the use of the index is a little better, the application runs a little faster.
id
select_type
table
type
possible_keys
key
key_len
ref
rows
Extra
1
PRIMARY
b
ref
idx_tri,idx_ligne_membre,idx_ligne_date_idbloc
idx_ligne_date_idbloc
1
const
58252
Using where; Using index
2
DEPENDENT SUBQUERY
TB
eq_ref
PRIMARY,id_bloc,id_taxon
PRIMARY
8
const,sitajeuxtestbourrage.b.id_bloc
1
Using index
Extra = « using Where, Using Index »
My questions:
id_bloc does not appear in the where and order by clauses, why am I required to add id_bloc on my multiple index ?
And Why rows = (again) all my table ? And not 20 (LIMIT 0,20)
You seem to have a misunderstanding what "Using Index" means in the Extra column. Have a look at this french explanation: http://use-the-index-luke.com/fr/sql/plans-dexecution/mysql/operations
id_bloc does not appear in the where and order by clauses, why am I required to add id_bloc on my multiple index ?
You are not required to, but doing so allows a so-called index-only scan (which is indicated by the words "Using Index" in Extra). You can learn about index-only scan at this french page: http://use-the-index-luke.com/fr/sql/regrouper-les-donnees/parcours-d-index-couvrants