2012-12-16 9 views
10

mam tej kwerendy ActiveRecordZastosowanie specyficzny indeks mysql z szynami

issue = Issue.find(id) 
issue.articles.includes(:category).merge(Category.where(permalink: perma)) 

I przetłumaczony na zapytania mysql

SELECT `articles`.`id` AS t0_r0, `articles`.`title` AS t0_r1, 
     `articles`.`hypertitle` AS t0_r2, `articles`.`html` AS t0_r3, 
     `articles`.`author` AS t0_r4, `articles`.`published` AS t0_r5, 
     `articles`.`category_id` AS t0_r6, `articles`.`issue_id` AS t0_r7, 
     `articles`.`date` AS t0_r8, `articles`.`created_at` AS t0_r9, 
     `articles`.`updated_at` AS t0_r10, `articles`.`photo_file_name` AS t0_r11, 
     `articles`.`photo_content_type` AS t0_r12, `articles`.`photo_file_size` AS t0_r13, 
     `articles`.`photo_updated_at` AS t0_r14, `categories`.`id` AS t1_r0, 
     `categories`.`name` AS t1_r1, `categories`.`permalink` AS t1_r2, 
     `categories`.`created_at` AS t1_r3, `categories`.`updated_at` AS t1_r4, 
     `categories`.`issued` AS t1_r5, `categories`.`order_articles` AS t1_r6 
     FROM `articles` LEFT OUTER JOIN `categories` ON 
     `categories`.`id` = `articles`.`category_id` WHERE 
     `articles`.`issue_id` = 409 AND `categories`.`permalink` = 'Διεθνή' LIMIT 1 

W explation tego zapytania Widziałem, że używa niewłaściwego indeks

+----+-------------+------------+-------+---------------------------------------------------------------------------+-------------------------------+---------+-------+------+----------+-------------+ 
| id | select_type | table  | type | possible_keys                | key       | key_len | ref | rows | filtered | Extra  | 
+----+-------------+------------+-------+---------------------------------------------------------------------------+-------------------------------+---------+-------+------+----------+-------------+ 
| 1 | SIMPLE  | categories | const | PRIMARY,index_categories_on_permalink          | index_categories_on_permalink | 768  | const | 1 | 100.00 |    | 
| 1 | SIMPLE  | articles | ref | index_articles_on_issue_id_and_category_id, index_articles_on_category_id | index_articles_on_category_id | 2  | const | 10 | 100.05 | Using where | 
+----+-------------+------------+-------+---------------------------------------------------------------------------+-------------------------------+---------+-------+------+----------+-------------+ 

Mam dwa indeksy, category_id sam i issue_id - category_id.

W tym zapytaniu szukam z issue_id i category_id, który jest znacznie szybszy w przypadku korzystania z index_articles_on_issue_id_and_category_id niż index_articles_on_category_id.

Jak wybrać poprawny indeks z aktywnym zapytaniem o rekord?

+0

Mike na konkretnym przykładzie, można użyć tylko jeden Composite Index, aby osiągnąć takie same wyniki. Jeśli masz zapytania, które używają tylko category_id i innych, które używają category_id i issu_id (combined), poprawnym indeksem będzie "index_articles_on_category_id_and_issue_id". Przy takim złożonym indeksie możesz wykorzystać oba rodzaje zapytań. Rzuć okiem na ten http://stackoverflow.com/questions/1823685/when-should-i-use-a-composite-index – alup

Odpowiedz

23

Można ułatwić Arel tak jak użycie indeksu:

class Issue 
    def self.use_index(index) 
    # update: OP fixed my mistake 
    from("#{self.table_name} USE INDEX(#{index})") 
    end 
end 

# then 
Issue.use_index("bla").where(some_condition: true) 
+2

Dzięki, działa z małą poprawką 'from (" # {self.table_name} USE INDEX (# {index}) ")' –