Hi,

On Sat, Mar 24, 2001 at 02:04:57PM +0100, Federico Giannici wrote:
> Fred van Engen wrote:
> > On Fri, Mar 23, 2001 at 07:46:48PM +0100, Federico Giannici wrote:
> > > We have a table where we register the data of all the modem connections
> > > of the users of a small ISP.
> > >
> > > The table contains 2 million records and has the following structure:
> > >
> > 
> > ...
> > 
> > What indexes does the table have? Looking at your description below
> > I would guess at least an index on start and an index on login.
> > 
> > SHOW CREATE TABLE tblname;
> 
> CREATE TABLE `accountings` (
>   `start` int(10) unsigned NOT NULL default '0',
>   `duration` int(10) unsigned NOT NULL default '0',
>   `login` char(8) NOT NULL default '',
>   `nas` int(10) unsigned NOT NULL default '0',
>   `port` int(10) unsigned NOT NULL default '0',
>   `ip` int(10) unsigned NOT NULL default '0',
>   `bytesrx` int(10) unsigned NOT NULL default '0',
>   `bytestx` int(10) unsigned NOT NULL default '0',
>   `speedtx` int(10) unsigned NOT NULL default '0',
>   `speedrx` int(10) unsigned NOT NULL default '0',
>   `telto` char(15) NOT NULL default '',
>   `telfrom` char(15) NOT NULL default '',
>   `multilinkid` int(10) unsigned NOT NULL default '0',
>   `sessionid` char(8) binary NOT NULL default '',
>   KEY `login`(`login`),
>   PRIMARY KEY (`start`,`nas`,`port`)
> ) TYPE=MyISAM PACK_KEYS=1
> 
> 
> > Also, which version of MySQL do you use?
> 
> MySQL 3.23.32 on OpenBSD 2.7 i386.
> 

Maybe someone can comment on optimization errors in this version, but
it should be one of the best versions there is (I use 3.23.33 with a
patch).


> > > According to us there is a bad optimization with queries like the
> > > following one:
> > >
> > > SELECT * FROM accountings WHERE start >= UNIX_TIMESTAMP('2001-03-23')
> > > AND login = 'anyname'
> > >
> > 
> > What does EXPLAIN say? I.e.
> 
> +-------------+------+---------------+-------+---------+-------+------+------------+
> | table       | type | possible_keys | key   | key_len | ref   | rows |
> Extra      |
> +-------------+------+---------------+-------+---------+-------+------+------------+
> | accountings | ref  | login,PRIMARY | login |       8 | const | 2428 |
> where used |
> +-------------+------+---------------+-------+---------+-------+------+------------+
> 

This would seem to be the logical index to use if there are more than
2428 rows with start >= UNIX_TIMESTAMP('2001-03-23').

Maybe the following query will show that:

EXPLAIN SELECT * FROM accountings USE INDEX (PRIMARY)
 WHERE start >= UNIX_TIMESTAMP('2001-03-23') AND login = 'anyname'

Of course, we know that the logins are not stored close together in
the data file, so it takes more time to scan them than scanning from
a certain start time. MySQL would never take this into account I
think. Not much you can do then, besides 'USE INDEX'.


> Does the previous EXPLAIN shows the reason?
> 
> Perhaps because possible_keys lists "login" before "PRIMARY"?
> 

The order shouldn't matter unless both EXPLAINs are equal.


> > > I don't know why the second condition is much slower than the first one,
> > > even if both the columns are indexed. Perhaps because "login" is a MUL
> > > index?
> > >
> > 
> > Is there anything special about this login? Is it used more often
> > than average?
> 
> This behaviour occurs with all the logins that have a good presence in
> the table. The result is almost immediate with the logins that have
> almost no records, but they are not the average...
> 

I was asking because I once had a similar situation where I tested
with a signup account. This had many more entries than average and
made the case just more noticable (until I explicitly set specified
the index to use).


> > > Is it possible to optimize the current behavior?
> > >
> > 
> > Yes, you can use this:
> > 
> > SELECT * FROM accountings USE INDEX (myindex)
> >  WHERE start >= UNIX_TIMESTAMP('2001-03-23') AND login = 'anyname'
> > 
> > Replace myindex with the index on start.
> 
> Wow, it worked!
> The query time sensibly decreased specifing "USE INDEX(PRIMARY)".
> 
> I wasn't able to find the documentation about the "USE INDEX()"
> parameter of the SELECT command in the on-line manual...
> 

Yes, I once knew I had seen it, but only managed to find it through
the search function of the website. Now I remember, it's in the
explanation of JOINs.


Regards,

Fred.

-- 
Fred van Engen                              XO Communications B.V.
email: [EMAIL PROTECTED]             Televisieweg 2
tel: +31 36 5462400                         1322 AC  Almere
fax: +31 36 5462424                         The Netherlands

---------------------------------------------------------------------
Before posting, please check:
   http://www.mysql.com/manual.php   (the manual)
   http://lists.mysql.com/           (the list archive)

To request this thread, e-mail <[EMAIL PROTECTED]>
To unsubscribe, e-mail <[EMAIL PROTECTED]>
Trouble unsubscribing? Try: http://lists.mysql.com/php/unsubscribe.php

Reply via email to