Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>For your query to run fast, you need:</p> <ol> <li><p>Create an index: <code>CREATE INDEX ix_timestamp_id ON items (timestamp, id)</code></p> <ul> <li>Ensure that <code>id</code>'s on <code>sources</code>, <code>authors</code> and <code>keywords</code> are primary keys.</li> <li><p>Force MySQL to use this index for items, and perform <code>NESTED LOOP</code> joins for other items:</p> <p>EXPLAIN EXTENDED SELECT <code>Item</code>.*, <code>Source</code> . * , <code>Keyword</code> . * , <code>Author</code> . * FROM <code>items</code> AS <code>Item</code> FORCE INDEX FOR ORDER BY (ix_timestamp_id) JOIN <code>items_keywords</code> AS <code>ItemsKeyword</code> FORCE INDEX (ix_item_keyword) ON ( <code>Item</code>.<code>id</code> = <code>ItemsKeyword</code>.<code>item_id</code> AND <code>ItemsKeyword</code>.<code>keyword_id</code> IN ( SELECT <code>keyword_id</code> FROM <code>keywords_profiles</code> AS <code>KeywordsProfile</code> FORCE INDEX (ix_keyword_profile) WHERE <code>KeywordsProfile</code>.<code>profile_id</code> = 17 ) ) JOIN <code>sources</code> AS <code>Source</code> FORCE INDEX (primary) ON ( <code>Item</code>.<code>source_id</code> = <code>Source</code>.<code>id</code> ) JOIN <code>authors</code> AS <code>Author</code> FORCE INDEX (primary) ON ( <code>Item</code>.<code>author_id</code> = <code>Author</code>.<code>id</code> ) JOIN <code>keywords</code> AS <code>Keyword</code> FORCE INDEX (primary) ON ( <code>Keyword</code>.<code>id</code> = <code>ItemsKeyword</code>.<code>keyword_id</code> ) ORDER BY <code>Item</code>.timestamp DESC, <code>Item</code>.id DESC LIMIT 0, 20</p></li> </ul></li> </ol> <p>As you can see, we get rid of <code>GROUP BY</code>, push the subquery into the <code>JOIN</code> condition and force <code>PRIMARY KEY</code>s to be used for joins.</p> <p>That's how we ensure that <code>NESTED LOOPS</code> with <code>items</code> as a leading tables will be used for all joins.</p> <p>As a result:</p> <pre> 1, 'PRIMARY', 'Item', 'index', '', 'ix_timestamp_id', '12', '', 20, 2622845.00, '' 1, 'PRIMARY', 'Author', 'eq_ref', 'PRIMARY', 'PRIMARY', '4', 'test.Item.author_id', 1, 100.00, '' 1, 'PRIMARY', 'Source', 'eq_ref', 'PRIMARY', 'PRIMARY', '4', 'test.Item.source_id', 1, 100.00, '' 1, 'PRIMARY', 'ItemsKeyword', 'ref', 'PRIMARY', 'PRIMARY', '4', 'test.Item.id', 1, 100.00, 'Using where; Using index' 1, 'PRIMARY', 'Keyword', 'eq_ref', 'PRIMARY', 'PRIMARY', '4', 'test.ItemsKeyword.keyword_id', 1, 100.00, '' 2, 'DEPENDENT SUBQUERY', 'KeywordsProfile', 'unique_subquery', 'PRIMARY', 'PRIMARY', '8', 'func,const', 1, 100.00, 'Using index; Using where' </pre> <p>, and when we run this, we get</p> <pre><code>20 rows fetched in 0,0038s (0,0019s) </code></pre> <p>There are <code>500k</code> in <code>items</code>, <code>600k</code> in <code>items_keywords</code>, <code>512</code> values in <code>keywords</code> and <code>512</code> values in <code>keywords_profiles</code> (all with profile <code>17</code>).</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload