Hi Richard!
Step 1
---------------
Is it right?
1. `threadid` value is unique.
2. `threadid` value is auto_increment.
3. if `threadid`(2) > `threadid`(1) => `created`(2) > `created`(1).
You can do the following:
1. Create the index on two fields: (boardid, status)
2. ALTER TABLE `board` ORDER BY `threadid` DESC;
Here is new query to fetch a block of records:
SELECT * FROM `board` WHERE `boardid` = 1 AND `status` = "L" LIMIT
100,50
Step 2
----------------
The average size of row in your table is 128,000,000 / 190,000 ~= 675
bytes.
Split your table in two tables, like:
CREATE TABLE `boardinfo`
( `threadid` INT(4) UNSIGNED AUTO_INCREMENT,
PRIMARY KEY( `threadid` ),
`boardid` INT(4) UNSIGNED,
`status` ENUM( 'L', '....' ),
`created` TIMESTAMP
... (all fixed fields )
)
ALTER TABLE `boardinfo` CREATE INDEX `main` (`boardid,`status`)
ALTER TABLE `boardinfo` ORDER BY `threadid` DESC
CREATE TABLE `boarddata` (
`threadid_ref` INT(4) UNSIGNED,
PRIMARY KEY ( `threadid_ref` ),
`threaddata` LONGTEXT
)
Here is your query after:
SELECT * FROM `boardinfo` LEFT JOIN `boarddata` ON `threadid` =
`threadid_ref` WHERE `boardid` = 1 AND `status` = "L" LIMIT 100,50
Sorry for my englist.
Best regards, Pavel
> Hi all,
>
> I have what is probably a quite standard question and would love to
> know how you would all approach this scenario:
>
> I have a table in a database that has approx. 190,000 records in it.
> The table is currently 128MB in size and I'm happy that it is well
> constructed with no data duplication and sensible indexes.
>
> I'm using MySQL 3.28.58. and my question is about querying this volume
> of data efficiently.
>
> The table holds forum threads (several years worth) so a common query
> running on the table is to bring back the top 50 or 100 threads from a
> board within the forum.
>
> To do this I'm using a LIMIT on my query and for the paging through
> the data (i.e. the first 100 threads, the next 100, etc) I use the
> LIMIT n,x syntax. Threads are sorted by date (most recent to the top).
>
> This is fine and it works well but I'm concerned it's not the most
> efficient way to do this because the use of LIMIT is causing the
> whole table to be scanned each time.
>
> Here is a typical (simplified) query:
>
> SELECT *
> FROM thread
> WHERE
> thread.status='L' AND
> thread.boardid=1
> ORDER BY created DESC
> LIMIT 100,50
>
> This takes over 1.02 seconds to process.
>
> Running an EXPLAIN on my query shows that it's using one key
> (boardid), but in the Extra field it shows it is having to use a
> filesort on the data. 5701 rows were used in order to bring back the
> final 50 - that's every single thread for this board.
>
> What I'm trying to figure out is a more efficient way of selecting a
> block of 50 or 100 records from any point in my table without MySQL
> needing to sort/check them all first.
>
> One thought I did have was that the Primary Key on my table is called
> threadid - and I thought that instead of bring back the data in my
> original query, I could collect nothing but the thread IDs and then
> use a separate query that does something like: "SELECT * FROM thread
> WHERE threadid IN (...)" (where ... = all of the IDs previously
> selected). Would the fact that threadid is my primary key make the
> original LIMIT/sort faster?
>
> Any thoughts appreciated.
>
> --
> Best regards,
> Richard Davey
> http://www.phpcommunity.org/wiki/296.html
--
PHP Database Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php