Fred van Engen wrote:
> 
> Hi,
> 
> 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.


> > 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 |
+-------------+------+---------------+-------+---------+-------+------+------------+


> > If we issue a query with only the first part of the condition ("SELECT *
> > FROM accountings WHERE start >= UNIX_TIMESTAMP('2001-03-23')") the
> > result is almost immediate.
> >
> 
> Depending on your indexes, MySQL will scan only the records that were
> added since the 23rd. Because you probably insert the records more or
> less on start time, they should be close together, which makes this fast.
> 
> > If we issue a query with only the second part of the condition ("SELECT
> > * FROM accountings WHERE login = 'anyname'") the result is given after
> > about 20 seconds.
> >
> 
> I guess you have an index on login as well, but if there are many records
> for this login (you keep a long history?), MySQL needs to fetch all these
> records. These are spread all over the database file, which can make this
> even slower than the number of records would suggest.
> 
> > The complete query, with both the conditions, lasts almost 20 seconds
> > too, even if the result was only a few rows!
> >
> 
> MySQL uses the wrong index. EXPLAIN may show why it does that.

Does the previous EXPLAIN shows the reason?

Perhaps because possible_keys lists "login" before "PRIMARY"?


> > 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...


> > Anyway, the most important question is another. If the result of the
> > first condition is only a few rows, we expected that the combination of
> > both conditions was not sensibly slower than the first condition alone.
> > Why were we wrong?
> >
> 
> I've only seen this on MERGE tables. Do you use them?

No.


> > 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...


> 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

Thank you!

___________________________________________________
    __
   |-                      [EMAIL PROTECTED]
   |ederico Giannici      http://www.neomedia.it
___________________________________________________

---------------------------------------------------------------------
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