There is a table of goods (goods more than 10 million), for each product a category key (catID) and a product serial number in this category (numInCat) are given:
CREATE TABLE `goods` ( `id` INT(9) UNSIGNED NOT NULL AUTO_INCREMENT, `catID` SMALLINT(2) UNSIGNED NOT NULL DEFAULT '0', `numInCat` MEDIUMINT(8) UNSIGNED NOT NULL DEFAULT '0', `name` VARCHAR(512) NULL DEFAULT NULL, # ... PRIMARY KEY (`id`), INDEX `catIDnumInCat` (`catID`, `numInCat`), ) ENGINE=InnoDB; Record example:
id=10352230 catID=67 numInCat=4936929 name='пакет с пупырышками' ... You need to select 3 products from the category catID = 67 starting with the sequence number numInCat = 4936929 + 1 in order of numInCat:
SELECT id,name FROM `goods` WHERE catID=67 AND numInCat>4936929 LIMIT 3 This request is executed in 1 second, which is very long for an online store. The operator EXPLAIN shows that the index catIDnumInCat is used, but 3086114 records are being searched! (key = catIDnumInCat, rows = 3086114)
If the request is changed to:
SELECT id,name FROM `goods` WHERE catID=67 AND numInCat>4936929 AND numInCat<=4936929+3 LIMIT 3 Then it runs instantly. With this, according to the EXPLAIN operator, 3 entries are being moved.
But the query in this form is not suitable, since products with numInCat = 4936930,4936931,4936932 can simply be deleted earlier.
Q: Why does my first SELECT query iterate through so many rows in a database? Index catIDnumInCat because built and used.
To use ORDER BY catID, numInCat tried - to no avail. Yes, and this design if I make a mistake works after receiving the result.
select id, name from ... where id in(select id from ... where catid.. numincat... order by ... limit 3), sometimes this helps the optimizer - Mike