dbTalk Databases Forums  

Index question...

comp.databases.mysql comp.databases.mysql


Discuss Index question... in the comp.databases.mysql forum.



Reply
 
Thread Tools Display Modes
  #11  
Old   
Jerry Stuckle
 
Posts: n/a

Default Re: Index question... - 07-19-2006 , 05:55 AM






howachen (AT) gmail (DOT) com wrote:
Quote:
Bill Karwin 寫道:


howachen (AT) gmail (DOT) com wrote:

i don't understand how index on FK will improve performane, IF ONLY ONE
(i.e. PK) index can be used at a time

MySQL can use one index per table. Your example named table "a" and
table "b". So it may use the primary key index from table "a" and the
foreign key index from table "b".

That's one index per table. If you have two tables, it may use two indexes.



thanks for your reply first...but the point is:

1. when joining two tables as above, only one index is used in the
whole query execution

my question is : why we need to create additional index on FK if MySQL
only can either use index PK or FK? why not force them to use PK (a.id)
and drop the index on b.fid (so as to save space and improve
insert/update performance)

thanks...

Howard,

You're missing the point. MySQL CAN use one index PER TABLE. Since you
have two tables, it can use one index in each, or a total of two indexes.

As to why it's only using one index. If you don't have an index on the
foreign key, it obviously can't use that index. But just because you do
have an index doesn't mean MySQL WILL use it. The optimizer may
determine it would be faster to just read the table than to use the
index. This is something it does on the fly

--
==================
Remove the "x" from my email address
Jerry Stuckle
JDS Computer Training Corp.
jstucklex (AT) attglobal (DOT) net
==================


Reply With Quote
  #12  
Old   
AT
 
Posts: n/a

Default Re: Index question... - 07-19-2006 , 09:14 AM







Jerry Stuckle 寫道:

Quote:
howachen (AT) gmail (DOT) com wrote:
Bill Karwin 寫道:


howachen (AT) gmail (DOT) com wrote:

i don't understand how index on FK will improve performane, IF ONLY ONE
(i.e. PK) index can be used at a time

MySQL can use one index per table. Your example named table "a" and
table "b". So it may use the primary key index from table "a" and the
foreign key index from table "b".

That's one index per table. If you have two tables, it may use two indexes.



thanks for your reply first...but the point is:

1. when joining two tables as above, only one index is used in the
whole query execution

my question is : why we need to create additional index on FK if MySQL
only can either use index PK or FK? why not force them to use PK (a.id)
and drop the index on b.fid (so as to save space and improve
insert/update performance)

thanks...


Howard,

You're missing the point. MySQL CAN use one index PER TABLE. Since you
have two tables, it can use one index in each, or a total of two indexes.

As to why it's only using one index. If you don't have an index on the
foreign key, it obviously can't use that index. But just because you do
have an index doesn't mean MySQL WILL use it. The optimizer may
determine it would be faster to just read the table than to use the
index. This is something it does on the fly

--
==================
Remove the "x" from my email address
Jerry Stuckle
JDS Computer Training Corp.
jstucklex (AT) attglobal (DOT) net
==================

Hi all, I think I should give a detail example to show my
question...sorry for that first....

DROP TABLE IF EXISTS `a`;
CREATE TABLE `a` (
`id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY ,
`fid` INT NOT NULL
) TYPE = myisam;

INSERT INTO `a` ( `id` , `fid` )
VALUES (NULL , '2'), (NULL , '3'), (NULL , '4'), (NULL , '5'), (NULL ,
'6'), (NULL , '7');

DROP TABLE IF EXISTS `b`;
CREATE TABLE `b` (
`id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY ,
`test` INT NOT NULL
) TYPE = myisam;

INSERT INTO `b` ( `id` , `test` )
VALUES (NULL , '1'), (NULL , '2'), (NULL , '3'), (NULL , '4'), (NULL ,
'5'), (NULL , '6');

ALTER TABLE `a` ADD INDEX ( `fid` )

EXPLAIN SELECT * FROM a FORCE INDEX(fid), b WHERE a.fid = b.id

id select_type table type possible_keys key key_len ref rows
Extra
1 SIMPLE a ALL fid NULL NULL NULL 6
1 SIMPLE b eq_ref PRIMARY PRIMARY 4 test.a.fid 1


Q. the index `fid` is completely useless, we can't have both b.id and
a.fid being used at the same time!
why not drop the a.fid (consider we don't use FK integrity checking
when using MyISAM)



Reply With Quote
  #13  
Old   
Jerry Stuckle
 
Posts: n/a

Default Re: Index question... - 07-19-2006 , 01:12 PM



howachen (AT) gmail (DOT) com wrote:
Quote:
Jerry Stuckle 寫道:


howachen (AT) gmail (DOT) com wrote:

Bill Karwin 寫道:



howachen (AT) gmail (DOT) com wrote:


i don't understand how index on FK will improve performane, IF ONLY ONE
(i.e. PK) index can be used at a time

MySQL can use one index per table. Your example named table "a" and
table "b". So it may use the primary key index from table "a" and the
foreign key index from table "b".

That's one index per table. If you have two tables, it may use two indexes.



thanks for your reply first...but the point is:

1. when joining two tables as above, only one index is used in the
whole query execution

my question is : why we need to create additional index on FK if MySQL
only can either use index PK or FK? why not force them to use PK (a.id)
and drop the index on b.fid (so as to save space and improve
insert/update performance)

thanks...


Howard,

You're missing the point. MySQL CAN use one index PER TABLE. Since you
have two tables, it can use one index in each, or a total of two indexes.

As to why it's only using one index. If you don't have an index on the
foreign key, it obviously can't use that index. But just because you do
have an index doesn't mean MySQL WILL use it. The optimizer may
determine it would be faster to just read the table than to use the
index. This is something it does on the fly

--
==================
Remove the "x" from my email address
Jerry Stuckle
JDS Computer Training Corp.
jstucklex (AT) attglobal (DOT) net
==================



Hi all, I think I should give a detail example to show my
question...sorry for that first....

DROP TABLE IF EXISTS `a`;
CREATE TABLE `a` (
`id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY ,
`fid` INT NOT NULL
) TYPE = myisam;

INSERT INTO `a` ( `id` , `fid` )
VALUES (NULL , '2'), (NULL , '3'), (NULL , '4'), (NULL , '5'), (NULL ,
'6'), (NULL , '7');

DROP TABLE IF EXISTS `b`;
CREATE TABLE `b` (
`id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY ,
`test` INT NOT NULL
) TYPE = myisam;

INSERT INTO `b` ( `id` , `test` )
VALUES (NULL , '1'), (NULL , '2'), (NULL , '3'), (NULL , '4'), (NULL ,
'5'), (NULL , '6');

ALTER TABLE `a` ADD INDEX ( `fid` )

EXPLAIN SELECT * FROM a FORCE INDEX(fid), b WHERE a.fid = b.id

id select_type table type possible_keys key key_len ref rows
Extra
1 SIMPLE a ALL fid NULL NULL NULL 6
1 SIMPLE b eq_ref PRIMARY PRIMARY 4 test.a.fid 1


Q. the index `fid` is completely useless, we can't have both b.id and
a.fid being used at the same time!
why not drop the a.fid (consider we don't use FK integrity checking
when using MyISAM)

Howard,

As Peter indicated, fid is not defined as a foreign key. But you are
using it for matching.

Obviously, the optimizer in this case determined it would be more
efficient to just scan the table instead of using the index. It is
perfectly valid for it to do so - and in fact, is a good thing. It
means the optimizer is doing its job.

Just because an index exists doesn't mean the optimizer has to use it.
The optimizer is perfectly able to ignore the index if access may be slower.




--
==================
Remove the "x" from my email address
Jerry Stuckle
JDS Computer Training Corp.
jstucklex (AT) attglobal (DOT) net
==================


Reply With Quote
  #14  
Old   
AT
 
Posts: n/a

Default Re: Index question... - 07-19-2006 , 09:15 PM




Jerry Stuckle 寫道:

Quote:
howachen (AT) gmail (DOT) com wrote:
Jerry Stuckle 寫道:


howachen (AT) gmail (DOT) com wrote:

Bill Karwin 寫道:



howachen (AT) gmail (DOT) com wrote:


i don't understand how index on FK will improve performane, IF ONLY ONE
(i.e. PK) index can be used at a time

MySQL can use one index per table. Your example named table "a" and
table "b". So it may use the primary key index from table "a" and the
foreign key index from table "b".

That's one index per table. If you have two tables, it may use two indexes.



thanks for your reply first...but the point is:

1. when joining two tables as above, only one index is used in the
whole query execution

my question is : why we need to create additional index on FK if MySQL
only can either use index PK or FK? why not force them to use PK (a.id)
and drop the index on b.fid (so as to save space and improve
insert/update performance)

thanks...


Howard,

You're missing the point. MySQL CAN use one index PER TABLE. Since you
have two tables, it can use one index in each, or a total of two indexes.

As to why it's only using one index. If you don't have an index on the
foreign key, it obviously can't use that index. But just because you do
have an index doesn't mean MySQL WILL use it. The optimizer may
determine it would be faster to just read the table than to use the
index. This is something it does on the fly

--
==================
Remove the "x" from my email address
Jerry Stuckle
JDS Computer Training Corp.
jstucklex (AT) attglobal (DOT) net
==================



Hi all, I think I should give a detail example to show my
question...sorry for that first....

DROP TABLE IF EXISTS `a`;
CREATE TABLE `a` (
`id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY ,
`fid` INT NOT NULL
) TYPE = myisam;

INSERT INTO `a` ( `id` , `fid` )
VALUES (NULL , '2'), (NULL , '3'), (NULL , '4'), (NULL , '5'), (NULL ,
'6'), (NULL , '7');

DROP TABLE IF EXISTS `b`;
CREATE TABLE `b` (
`id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY ,
`test` INT NOT NULL
) TYPE = myisam;

INSERT INTO `b` ( `id` , `test` )
VALUES (NULL , '1'), (NULL , '2'), (NULL , '3'), (NULL , '4'), (NULL ,
'5'), (NULL , '6');

ALTER TABLE `a` ADD INDEX ( `fid` )

EXPLAIN SELECT * FROM a FORCE INDEX(fid), b WHERE a.fid = b.id

id select_type table type possible_keys key key_len ref rows
Extra
1 SIMPLE a ALL fid NULL NULL NULL 6
1 SIMPLE b eq_ref PRIMARY PRIMARY 4 test.a.fid 1


Q. the index `fid` is completely useless, we can't have both b.id and
a.fid being used at the same time!
why not drop the a.fid (consider we don't use FK integrity checking
when using MyISAM)


Howard,

As Peter indicated, fid is not defined as a foreign key. But you are
using it for matching.

Obviously, the optimizer in this case determined it would be more
efficient to just scan the table instead of using the index. It is
perfectly valid for it to do so - and in fact, is a good thing. It
means the optimizer is doing its job.

Just because an index exists doesn't mean the optimizer has to use it.
The optimizer is perfectly able to ignore the index if access may be slower.


i have used the "FORCE INDEX(fid)"

why table scan still occur?



Reply With Quote
  #15  
Old   
Jerry Stuckle
 
Posts: n/a

Default Re: Index question... - 07-19-2006 , 10:43 PM



howachen (AT) gmail (DOT) com wrote:
Quote:
Jerry Stuckle 寫道:


howachen (AT) gmail (DOT) com wrote:

Jerry Stuckle 寫道:



howachen (AT) gmail (DOT) com wrote:


Bill Karwin 寫道:




howachen (AT) gmail (DOT) com wrote:



i don't understand how index on FK will improve performane, IF ONLY ONE
(i.e. PK) index can be used at a time

MySQL can use one index per table. Your example named table "a" and
table "b". So it may use the primary key index from table "a" and the
foreign key index from table "b".

That's one index per table. If you have two tables, it may use two indexes.



thanks for your reply first...but the point is:

1. when joining two tables as above, only one index is used in the
whole query execution

my question is : why we need to create additional index on FK if MySQL
only can either use index PK or FK? why not force them to use PK (a.id)
and drop the index on b.fid (so as to save space and improve
insert/update performance)

thanks...


Howard,

You're missing the point. MySQL CAN use one index PER TABLE. Since you
have two tables, it can use one index in each, or a total of two indexes.

As to why it's only using one index. If you don't have an index on the
foreign key, it obviously can't use that index. But just because you do
have an index doesn't mean MySQL WILL use it. The optimizer may
determine it would be faster to just read the table than to use the
index. This is something it does on the fly

--
==================
Remove the "x" from my email address
Jerry Stuckle
JDS Computer Training Corp.
jstucklex (AT) attglobal (DOT) net
==================



Hi all, I think I should give a detail example to show my
question...sorry for that first....

DROP TABLE IF EXISTS `a`;
CREATE TABLE `a` (
`id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY ,
`fid` INT NOT NULL
) TYPE = myisam;

INSERT INTO `a` ( `id` , `fid` )
VALUES (NULL , '2'), (NULL , '3'), (NULL , '4'), (NULL , '5'), (NULL ,
'6'), (NULL , '7');

DROP TABLE IF EXISTS `b`;
CREATE TABLE `b` (
`id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY ,
`test` INT NOT NULL
) TYPE = myisam;

INSERT INTO `b` ( `id` , `test` )
VALUES (NULL , '1'), (NULL , '2'), (NULL , '3'), (NULL , '4'), (NULL ,
'5'), (NULL , '6');

ALTER TABLE `a` ADD INDEX ( `fid` )

EXPLAIN SELECT * FROM a FORCE INDEX(fid), b WHERE a.fid = b.id

id select_type table type possible_keys key key_len ref rows
Extra
1 SIMPLE a ALL fid NULL NULL NULL 6
1 SIMPLE b eq_ref PRIMARY PRIMARY 4 test.a.fid 1


Q. the index `fid` is completely useless, we can't have both b.id and
a.fid being used at the same time!
why not drop the a.fid (consider we don't use FK integrity checking
when using MyISAM)


Howard,

As Peter indicated, fid is not defined as a foreign key. But you are
using it for matching.

Obviously, the optimizer in this case determined it would be more
efficient to just scan the table instead of using the index. It is
perfectly valid for it to do so - and in fact, is a good thing. It
means the optimizer is doing its job.

Just because an index exists doesn't mean the optimizer has to use it.
The optimizer is perfectly able to ignore the index if access may be slower.




i have used the "FORCE INDEX(fid)"

why table scan still occur?

Probably because "FORCE INDEX" is a recommendation, not an order. But
it also depends on the versions of MySQL you're using.

Try filling the table with 200K rows and see if things change.

--
==================
Remove the "x" from my email address
Jerry Stuckle
JDS Computer Training Corp.
jstucklex (AT) attglobal (DOT) net
==================


Reply With Quote
  #16  
Old   
AT
 
Posts: n/a

Default Re: Index question... - 07-19-2006 , 11:07 PM




Jerry Stuckle 寫道:

Quote:
howachen (AT) gmail (DOT) com wrote:
Jerry Stuckle 寫道:


howachen (AT) gmail (DOT) com wrote:

Jerry Stuckle 寫道:



howachen (AT) gmail (DOT) com wrote:


Bill Karwin 寫道:




howachen (AT) gmail (DOT) com wrote:



i don't understand how index on FK will improve performane, IF ONLY ONE
(i.e. PK) index can be used at a time

MySQL can use one index per table. Your example named table "a" and
table "b". So it may use the primary key index from table "a" and the
foreign key index from table "b".

That's one index per table. If you have two tables, it may use twoindexes.



thanks for your reply first...but the point is:

1. when joining two tables as above, only one index is used in the
whole query execution

my question is : why we need to create additional index on FK if MySQL
only can either use index PK or FK? why not force them to use PK (a.id)
and drop the index on b.fid (so as to save space and improve
insert/update performance)

thanks...


Howard,

You're missing the point. MySQL CAN use one index PER TABLE. Since you
have two tables, it can use one index in each, or a total of two indexes.

As to why it's only using one index. If you don't have an index on the
foreign key, it obviously can't use that index. But just because youdo
have an index doesn't mean MySQL WILL use it. The optimizer may
determine it would be faster to just read the table than to use the
index. This is something it does on the fly

--
==================
Remove the "x" from my email address
Jerry Stuckle
JDS Computer Training Corp.
jstucklex (AT) attglobal (DOT) net
==================



Hi all, I think I should give a detail example to show my
question...sorry for that first....

DROP TABLE IF EXISTS `a`;
CREATE TABLE `a` (
`id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY ,
`fid` INT NOT NULL
) TYPE = myisam;

INSERT INTO `a` ( `id` , `fid` )
VALUES (NULL , '2'), (NULL , '3'), (NULL , '4'), (NULL , '5'), (NULL ,
'6'), (NULL , '7');

DROP TABLE IF EXISTS `b`;
CREATE TABLE `b` (
`id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY ,
`test` INT NOT NULL
) TYPE = myisam;

INSERT INTO `b` ( `id` , `test` )
VALUES (NULL , '1'), (NULL , '2'), (NULL , '3'), (NULL , '4'), (NULL ,
'5'), (NULL , '6');

ALTER TABLE `a` ADD INDEX ( `fid` )

EXPLAIN SELECT * FROM a FORCE INDEX(fid), b WHERE a.fid = b.id

id select_type table type possible_keys key key_len ref rows
Extra
1 SIMPLE a ALL fid NULL NULL NULL 6
1 SIMPLE b eq_ref PRIMARY PRIMARY 4 test.a.fid 1


Q. the index `fid` is completely useless, we can't have both b.id and
a.fid being used at the same time!
why not drop the a.fid (consider we don't use FK integrity checking
when using MyISAM)


Howard,

As Peter indicated, fid is not defined as a foreign key. But you are
using it for matching.

Obviously, the optimizer in this case determined it would be more
efficient to just scan the table instead of using the index. It is
perfectly valid for it to do so - and in fact, is a good thing. It
means the optimizer is doing its job.

Just because an index exists doesn't mean the optimizer has to use it.
The optimizer is perfectly able to ignore the index if access may be slower.




i have used the "FORCE INDEX(fid)"

why table scan still occur?


Probably because "FORCE INDEX" is a recommendation, not an order. But
it also depends on the versions of MySQL you're using.

Try filling the table with 200K rows and see if things change.

accorinding to the doc...

You can also use FORCE INDEX, which acts like USE INDEX (key_list) but
with the addition that a table scan is assumed to be very expensive. In
other words, a table scan is used only if there is no way to use one of
the given indexes to find rows in the table.

USE INDEX is a recommendation, FORCE INDEX is not used ONLY if there is
no way to use one of the given indexes to find rows in the table.

so this also confirmed that fid is useless in joining table?

thanks....



Reply With Quote
  #17  
Old   
Kai Ruhnau
 
Posts: n/a

Default Re: Index question... - 07-20-2006 , 02:09 AM



howachen (AT) gmail (DOT) com wrote:
Quote:
Jerry Stuckle 寫道:

howachen (AT) gmail (DOT) com wrote:
Jerry Stuckle 寫道:


howachen (AT) gmail (DOT) com wrote:

Jerry Stuckle 寫道:



howachen (AT) gmail (DOT) com wrote:


Bill Karwin 寫道:




howachen (AT) gmail (DOT) com wrote:



i don't understand how index on FK will improve performane, IF ONLY ONE
(i.e. PK) index can be used at a time
MySQL can use one index per table. Your example named table "a" and
table "b". So it may use the primary key index from table "a" and the
foreign key index from table "b".

That's one index per table. If you have two tables, it may use two indexes.


thanks for your reply first...but the point is:

1. when joining two tables as above, only one index is used in the
whole query execution

my question is : why we need to create additional index on FK if MySQL
only can either use index PK or FK? why not force them to use PK (a.id)
and drop the index on b.fid (so as to save space and improve
insert/update performance)

thanks...

Howard,

You're missing the point. MySQL CAN use one index PER TABLE. Since you
have two tables, it can use one index in each, or a total of two indexes.

As to why it's only using one index. If you don't have an index on the
foreign key, it obviously can't use that index. But just because you do
have an index doesn't mean MySQL WILL use it. The optimizer may
determine it would be faster to just read the table than to use the
index. This is something it does on the fly

--
==================
Remove the "x" from my email address
Jerry Stuckle
JDS Computer Training Corp.
jstucklex (AT) attglobal (DOT) net
==================


Hi all, I think I should give a detail example to show my
question...sorry for that first....

DROP TABLE IF EXISTS `a`;
CREATE TABLE `a` (
`id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY ,
`fid` INT NOT NULL
) TYPE = myisam;

INSERT INTO `a` ( `id` , `fid` )
VALUES (NULL , '2'), (NULL , '3'), (NULL , '4'), (NULL , '5'), (NULL ,
'6'), (NULL , '7');

DROP TABLE IF EXISTS `b`;
CREATE TABLE `b` (
`id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY ,
`test` INT NOT NULL
) TYPE = myisam;

INSERT INTO `b` ( `id` , `test` )
VALUES (NULL , '1'), (NULL , '2'), (NULL , '3'), (NULL , '4'), (NULL ,
'5'), (NULL , '6');

ALTER TABLE `a` ADD INDEX ( `fid` )

EXPLAIN SELECT * FROM a FORCE INDEX(fid), b WHERE a.fid = b.id

id select_type table type possible_keys key key_len ref rows
Extra
1 SIMPLE a ALL fid NULL NULL NULL 6
1 SIMPLE b eq_ref PRIMARY PRIMARY 4 test.a.fid 1


Q. the index `fid` is completely useless, we can't have both b.id and
a.fid being used at the same time!
why not drop the a.fid (consider we don't use FK integrity checking
when using MyISAM)

Howard,

As Peter indicated, fid is not defined as a foreign key. But you are
using it for matching.

Obviously, the optimizer in this case determined it would be more
efficient to just scan the table instead of using the index. It is
perfectly valid for it to do so - and in fact, is a good thing. It
means the optimizer is doing its job.

Just because an index exists doesn't mean the optimizer has to use it.
The optimizer is perfectly able to ignore the index if access may be slower.



i have used the "FORCE INDEX(fid)"

why table scan still occur?

Probably because "FORCE INDEX" is a recommendation, not an order. But
it also depends on the versions of MySQL you're using.

Try filling the table with 200K rows and see if things change.


accorinding to the doc...

You can also use FORCE INDEX, which acts like USE INDEX (key_list) but
with the addition that a table scan is assumed to be very expensive. In
other words, a table scan is used only if there is no way to use one of
the given indexes to find rows in the table.

USE INDEX is a recommendation, FORCE INDEX is not used ONLY if there is
no way to use one of the given indexes to find rows in the table.

so this also confirmed that fid is useless in joining table?
No, plase do what Jerry proposed: Fill both tables with 200,000 entries
and try again. You will notice that many things change, once the
optimizer has to do *real work*.
Also try to fill one table with far less entries than the other table.
For example table a ~4000 Entries and table b ~200,000 Entries and the
other way around. Try distributing fid uneven for example let 150,000
entries from b point to the same entry in a and let only 2 entries from
b point to another one in a.
You will notice, that the optimizer takes different paths through the
joined tables, uses different indexes depending on for example
additional WHERE-conditions.

FORCE INDEX as you quoted from the manual only makes the table scan very
expensive. That does not mean, that MySQL will not use a table scan.
When you work with your little 6-entry table MySQL has the options to a)
read the Index and then read the corresponding data entries or b) read
all data entries (that means with the data used to join).
For your little table a) means two (expensive) read operations and b)
means only one. Which option would you choose?

Kai


Reply With Quote
Reply




Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off



Powered by vBulletin Version 3.5.3
Copyright ©2000 - 2012, Jelsoft Enterprises Ltd.