Jump to content

Optimizing Indexes in Big Tables


neoform

Recommended Posts

ok, so i've got this big query that deals with 3 rather large tables..  I've indexed all appropriate fields, yet the query still takes up to 15 seconds to load..  is there any way to get this going faster?

[code]SELECT
listings.id,
listings.url_name,
listings.name
FROM
keywords
INNER JOIN keywords_items ON keywords.id = keywords_items.keyword_id
INNER JOIN listings ON keywords_items.item_id = listings.id
WHERE
(word_stemmed IN ("advertis", "promot"))
AND
city = '33939'
GROUP BY listings.id
LIMIT 0, 15[/code]

[code]+----+-------------+----------------+--------+-----------------------+---------------+---------+---------------------------------------+------+-----------------------------------------------------------+
| id | select_type | table          | type  | possible_keys        | key          | key_len | ref                                  | rows | Extra                                                    |
+----+-------------+----------------+--------+-----------------------+---------------+---------+---------------------------------------+------+-----------------------------------------------------------+
|  1 | SIMPLE      | keywords      | range  | PRIMARY,word_stemmed  | word_stemmed  | 31      | NULL                                  |  20 | Using where; Using index; Using temporary; Using filesort |
|  1 | SIMPLE      | keywords_items | ref    | PRIMARY,keyword_index | keyword_index | 3      | localdirectory.keywords.id            |  66 |                                                          |
|  1 | SIMPLE      | listings      | eq_ref | PRIMARY,city,city_id  | PRIMARY      | 3      | localdirectory.keywords_items.item_id |    1 | Using where                                              |
+----+-------------+----------------+--------+-----------------------+---------------+---------+---------------------------------------+------+-----------------------------------------------------------+
[/code]


kewords (index: keyword_stemmed/id) this table has about 800,000 rows
[code]+--------------+-----------------------+------+-----+---------+----------------+
| Field        | Type                  | Null | Key | Default | Extra          |
+--------------+-----------------------+------+-----+---------+----------------+
| id          | mediumint(8) unsigned | NO  | PRI | NULL    | auto_increment |
| word        | char(30)              | YES  | UNI | NULL    |                |
| word_stemmed | char(30)              | YES  | MUL | NULL    |                |
+--------------+-----------------------+------+-----+---------+----------------+[/code]

Keywords_items (Indexed: keyword_id/item_id) this table has about 54,000,000 rows
[code]+------------+-----------------------+------+-----+---------+-------+
| Field      | Type                  | Null | Key | Default | Extra |
+------------+-----------------------+------+-----+---------+-------+
| item_id    | mediumint(8) unsigned | NO  | PRI | 0      |      |
| keyword_id | mediumint(8) unsigned | NO  | PRI | 0      |      |
| weight    | smallint(5) unsigned  | NO  |    |        |      |
+------------+-----------------------+------+-----+---------+-------+[/code]

Listings (index: city) this table has about 8,100,000 rows
[code]+-----------------+-----------------------+------+-----+---------+----------------+
| Field          | Type                  | Null | Key | Default | Extra          |
+-----------------+-----------------------+------+-----+---------+----------------+
| id              | mediumint(8) unsigned | NO  | PRI | NULL    | auto_increment |
| url_name        | char(50)              | YES  | UNI | NULL    |                |
| longitude      | double                | NO  | MUL |        |                |
| latitude        | double                | NO  |    |        |                |
| name            | char(255)            | YES  |    | NULL    |                |
| address        | char(255)            | YES  |    | NULL    |                |
| state          | smallint(5) unsigned  | YES  | MUL | NULL    |                |
| city            | mediumint(8) unsigned | YES  | MUL | NULL    |                |
| zip            | char(6)              | YES  |    | NULL    |                |
| phone          | char(10)              | YES  |    | NULL    |                |
| fax            | char(10)              | YES  |    | NULL    |                |
| email          | char(128)            | YES  |    | NULL    |                |
| website        | char(255)            | YES  |    | NULL    |                |
| description    | text                  | YES  |    | NULL    |                |
| hours          | text                  | YES  |    | NULL    |                |
| payment_options | text                  | YES  |    | NULL    |                |
| locations      | smallint(5) unsigned  | YES  |    | NULL    |                |
| established_on  | date                  | YES  |    | NULL    |                |
| image          | enum('yes','no')      | YES  |    | no      |                |
| keywords        | text                  | YES  |    | NULL    |                |
| added_on        | datetime              | YES  |    | NULL    |                |
| rating          | tinyint(3) unsigned  | YES  |    | NULL    |                |
+-----------------+-----------------------+------+-----+---------+----------------+[/code]
Link to comment
Share on other sites

This may be faster
[code]
SELECT
l.id, l.url_name, l.name
FROM
listings AS l
WHERE
id
IN
(
    SELECT
    i.item_id
    FROM
    keywords AS k
    INNER JOIN
    keywords_items AS i
    ON
    k.id = i.keyword_id
    WHERE
    word_stemmed IN ("advertis", "promot")
)
AND
city = '33939'
LIMIT 0, 15
[/code]

You can add an "ORDER BY id" if you're planning on going through the results in some order.

Also do an "ANALYZE TABLE" on each table.
http://dev.mysql.com/doc/refman/5.1/en/analyze-table.html
Link to comment
Share on other sites

Interesting approach, shoz... that's not what came to mind.  Maybe I was misled by that GROUP BY lying around -- but I like it!

You might even be able to tweak it further by separating the IN clause into two statements, depending on the speed; also, there may be a covering index opportunity here, especially useful if you do add the ORDER BY.
Link to comment
Share on other sites

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.