|
|
|
| Re: Mysql not using index for ORDER BY ? [message #1251 is a reply to message #1250 ] |
Sun, 13 May 2007 17:29   |
carpii Messages: 46 Registered: November 2006 |
Member |
|
|
| sterin wrote on Sun, 13 May 2007 17:15 |
Is this something with older versions?
|
Not that I know of. My experience is with MSSQL, but since they based it on the Sybase code, and arnoooooo came to the same concllusion, I assumed Sybase was the same.
In MSSQL, if you create a primary key on a table, it will, as you say, automatically add a clustered index on the same fields. That is, if a clustered index does not already exist - you can obviously only have one clustered index.
But this clustered index can be dropped, and you can add a clustered index to something else if you want. This does not affect the enforcement of the Primary Key constraint, although most likely it would affect performance of it.
|
|
|
|
| Re: Mysql not using index for ORDER BY ? [message #1255 is a reply to message #1252 ] |
Tue, 15 May 2007 05:24   |
arnoooooo Messages: 3 Registered: May 2007 |
Junior Member |
|
|
Thank you for your suggestions.
carpii, here is the schema for the table :
DESCRIBE histos_backtest ;
+-----------+------------+------+-----+-------------------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-----------+------------+------+-----+-------------------+----------------+
| id | bigint(20) | NO | PRI | NULL | auto_increment |
| isin | char(12) | NO | | | |
| exchange | char(4) | NO | | | |
| time | timestamp | NO | | CURRENT_TIMESTAMP | |
| field | varchar(5) | NO | | | |
| value | float | NO | | | |
| validated | tinyint(1) | NO | | | |
+-----------+------------+------+-----+-------------------+----------------+
7 rows in set (0.15 sec)
sterin : Yes, I am using a MyISAM table. I tried FORCE INDEX, and apparently, MySQL no longer uses a filesort. It seems to be preparing the query for hours however, until it apparently runs out of ram and starts swapping so much that it renders the whole system unusable ! I let it run for a few hours then decided to shut it down.
Is MySQL trying to cache all the rows before it returns them ? If I try to do a select on a few rows with arbitrary ids, it is very fast. I think I might resort to using a few millions of one row selects ?
[Updated on: Tue, 15 May 2007 05:25]
|
|
|
|
|
| Re: Mysql not using index for ORDER BY ? [message #1259 is a reply to message #1257 ] |
Tue, 15 May 2007 08:06   |
arnoooooo Messages: 3 Registered: May 2007 |
Junior Member |
|
|
carpii :
- I am using MySQL 5.0.27
- It does perform well with a LIMIT clause, although I have not tried a huge LIMIT clause, in which case I imagine the results would be the same ?
- Using a char field might be a good idea indeed.
sterin :
- Yes, I want all the rows returned. Or at least I will use all the rows in my program, even if I split the query into several smaller queries.
Considering that I will use the rows one by one, is it a mistake to use only one SELECT statement ?
I currently am doing the following to temporarily solve the problem :
I loop on "SELECT * FROM table WHERE id>XX ORDER BY id LIMIT 1"
where XX is initially set to -1 then set to the latest value of id fetched...
- Do you know how to get the equivalent of --quick within a Perl program using DBD::MySQL ?
[EDIT] apparently I can do that with the RowCacheSize hint... assuming DBD::MySQL supports it
[Updated on: Tue, 15 May 2007 08:08]
|
|
|
| Re: Mysql not using index for ORDER BY ? [message #1260 is a reply to message #1259 ] |
Tue, 15 May 2007 08:49  |
sterin Messages: 323 Registered: March 2007 Location: Sweden |
Senior Member |
|
|
When working with large databases learn to not think about using LIMIT think about using WHERE instead to limit the nr of rows returned from a query.
The reason is that LIMIT is evaluate last in the query while WHERE is evaluated first and the sooner that the DBMS can rule out unnecessary rows the better.
In your case if you are running a perl program that retrieves all rows for you and then process them.
I would suggest that you retrieve maybe 10,000 rows (or try some good figure) at a time and if your primary key is normal auto_increment then just use that in a WHERE to limit the nr of rows:
-- first select
SELECT * FROM yourTable WHERE id > 0 and id < 10000;
-- second select
SELECT * FROM yourTable WHERE id > 10000 and id < 20000;
-- etc
But naturally you implement this by using prepared statements to speed it up even further.
And even if you have deleted a lot of rows from the DB then it still doesn't really matter that you get exactly 10,000 rows each time.
Since you are looping thru the table until you reach the COUNT(*) rows in the table you will get all rows in the end anyway.
These individual select will perform a range scan on the index and the time to get them is not that different from selecting them all at once.
You will get a small overhead with each query but at the same time that will be pretty negligable if you select about 10,000 rows at a time.
|
|
|