R
R
ruslanbm292019-06-24 07:04:03
PHP
ruslanbm29, 2019-06-24 07:04:03

10 million MySQL records. How to paginate output in descending order?

There is a table in MySQL with over 10 million records. All this is located on a weak server.
it is necessary to make a page output on 50 records. The number of records increases, but in general the number of INSERT queries is small (50-100 per day), which does not affect performance. The site itself and pagination is implemented in PHP.
I don't need to delve into the oldest pagination posts, 200 pagination pages of 50 posts each will suffice.
In principle, it quickly fulfills "SELECT * FROM 1_vopros ORDER BY id DESC LIMIT $num OFFSET $start" - for the first 200 pages (less than a second) - which is what I need, but if I add WHERE st=1 for several seconds. (St 3 values ​​are either 0 or 1 or 2). But WHERE cat='3' (Works for speed depending on how many records with this value - the less the faster - cat is the ID of the category).
how to optimize query with adding conditions WHERE st='1' AND cat='category ID' in descending order by ID field? There is an index on these fields. Probyval and double indexes did not help.

CREATE TABLE IF NOT EXISTS `1_vopros` (
  `id` int(12) NOT NULL,
  `vopr` text NOT NULL,
  `title` varchar(255) NOT NULL,
  `url` varchar(255) NOT NULL,
  `autor` varchar(255) NOT NULL,
  `autorid` int(12) NOT NULL,
  `date` datetime NOT NULL,
  `cat` tinyint(2) NOT NULL,
  `kls` tinyint(2) NOT NULL,
  `srcid` varchar(255) NOT NULL,
  `st` tinyint(1) NOT NULL,
  `src` tinyint(1) NOT NULL,
  `imgs` text NOT NULL,
  `view` int(50) NOT NULL
) ENGINE=MyISAM AUTO_INCREMENT=12603144 DEFAULT CHARSET=utf8;

ALTER TABLE `1_vopros`
  ADD PRIMARY KEY (`id`),
  ADD UNIQUE KEY `srcid` (`srcid`),
  ADD KEY `st` (`st`),
  ADD KEY `url` (`url`),
  ADD KEY `cat` (`cat`),
  ADD KEY `kls` (`kls`),
  ADD KEY `autor` (`autor`),
  ADD KEY `date` (`date`),
  ADD FULLTEXT KEY `vopr` (`vopr`,`title`);

--
-- AUTO_INCREMENT для сохранённых таблиц
--

--
-- AUTO_INCREMENT для таблицы `1_vopros`
--
ALTER TABLE `1_vopros`
  MODIFY `id` int(12) NOT NULL AUTO_INCREMENT,AUTO_INCREMENT=12603144;
/*!40101 SET [email protected]_CHARACTER_SET_CLIENT */;
/*!40101 SET [email protected]_CHARACTER_SET_RESULTS */;
/*!40101 SET [email protected]_COLLATION_CONNECTION */;

Answer the question

In order to leave comments, you need to log in

1 answer(s)
L
Lazy @BojackHorseman PHP, 2019-06-24
@ruslanbm29

First of all, remove the comparison of integer fields with strings, which entails type casting and index suppression.
add index (cat, st, id desc) and show query result
update . fetching only the primary key field in the first query in this case requires only reading one index and does not require fetching records from disk, which is beneficial. then with the second request, by the obtained id values, select the required records with a simple quick request

SELECT * FROM 1_vopros WHERE id IN (<ids_list_separator_coma>);

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question