1. Mở đầu
Khi phát triển hoặc tối ưu Rails applications, một trong những công việc quan trọng đó là hiểu và tối ưu được các SQL queries vì phần lớn tốc độ web chậm là do các logic xử lý/ truy vấn DB chưa hợp lý. Chúng ta sẽ hỏi những câu hỏi như: Có bao nhiêu câu SQL queries được gọi sau mỗi lần request, mất bao nhiêu thời gian để hoàn thành một câu SQL query?, câu query có bị gọi lặp lại ở các nơi khác nhau trong code không?, câu query nào được gọi nhiều lần hơn các câu query khác?
Thông thường, chúng ta thường tìm ra chúng bằng cách check file log, nhưng nếu chúng ta muốn phân tích chi tiết một request hoặc nếu chúng ta muốn track nhiều requests cùng 1 lúc, sẽ rất khó để chúng ta tìm và lọc ra các thông tin liên quan trong log file.
Để trả lời cho các câu hỏi đó, Steven Yue đã tạo ra một gem tên là sql_tracker. Trong bài này, ta sẽ tìm hiểu cách hoạt động của gem sql_tracker và các tính năng của nó để giúp track và phân tích các SQL queries
Tracking
Về cơ bản, sql_tracker sử dụng instrumentation API để track các SQL queries được gọi ra từ Active Record thông qua việc theo dõi sql.active_record hook:
1 2 3 4 | <span class="token constant">ActiveSupport</span><span class="token punctuation">:</span><span class="token punctuation">:</span><span class="token constant">Notifications</span><span class="token punctuation">.</span>subscribe<span class="token punctuation">(</span><span class="token string">'sql.active_record'</span><span class="token punctuation">)</span> <span class="token keyword">do</span> <span class="token operator">|</span>_name<span class="token punctuation">,</span> _start<span class="token punctuation">,</span> _finish<span class="token punctuation">,</span> _id<span class="token punctuation">,</span> payload<span class="token operator">|</span> sql_query <span class="token operator">=</span> payload<span class="token punctuation">[</span><span class="token symbol">:sql</span><span class="token punctuation">]</span> <span class="token keyword">end</span> |
Thay vì việc sử dụng một block, ta có thể cung cấp một instance object, được cài đặt bởi call method:
1 2 3 4 5 6 7 8 | <span class="token keyword">class</span> <span class="token class-name">Handler</span> <span class="token keyword">def</span> <span class="token method-definition"><span class="token function">call</span></span><span class="token punctuation">(</span>_name<span class="token punctuation">,</span> _start<span class="token punctuation">,</span> _finish<span class="token punctuation">,</span> _id<span class="token punctuation">,</span> payload<span class="token punctuation">)</span> sql_query <span class="token operator">=</span> payload<span class="token punctuation">[</span><span class="token symbol">:sql</span><span class="token punctuation">]</span> <span class="token keyword">end</span> <span class="token keyword">end</span> <span class="token constant">ActiveSupport</span><span class="token punctuation">:</span><span class="token punctuation">:</span><span class="token constant">Notifications</span><span class="token punctuation">.</span>subscribe<span class="token punctuation">(</span><span class="token string">'sql.active_record'</span><span class="token punctuation">,</span> <span class="token constant">Handler</span><span class="token punctuation">.</span><span class="token keyword">new</span><span class="token punctuation">)</span> |
sql_tracker được khai báo và track các câu queries khi một Rails process chạy, và dừng việc tracking khi Rails process kết thúc.
Filtering
Ta có thể không muốn lắng nghe tất cả các câu queries. Ví dụ như chỉ muốn track những câu SELECT của các queries, hoặc ta muốn track các queries được gọi với một thư mục nhất định.
Mặc định, sql_tracker tracks và ghi lại tất cả 4 commands (SELECT, INSERT, UPDATE và DELETE), nhưng ta có thể thay đổi bằng việc thay đổi biến settings tracked_sql_command
1 2 | <span class="token constant">SqlTracker</span><span class="token punctuation">:</span><span class="token punctuation">:</span><span class="token constant">Config</span><span class="token punctuation">.</span>tracked_sql_command <span class="token operator">=</span> <span class="token string">%w(SELECT)</span> |
Mặc định, sql_tracker tracks thư mục app và lib folders để bỏ qua các queries không liên quan (ví dụ như queries được gọi từ thư mục tests).
Grouping
sql_tracker sẽ thử đơn giản hoá và gọp các câu queries bằng việc thay thế các giá trị đặc biệt với xxx. Ví dụ, nếu ta thực hiện một câu SQL query sau:
1 2 | <span class="token constant">SELECT</span> users<span class="token punctuation">.</span><span class="token operator">*</span> <span class="token constant">FROM</span> users <span class="token constant">WHERE</span> users<span class="token punctuation">.</span>id <span class="token operator">=</span> <span class="token number">1</span> |
và sau đó là một câu query khác:
1 2 | <span class="token constant">SELECT</span> users<span class="token punctuation">.</span><span class="token operator">*</span> <span class="token constant">FROM</span> users <span class="token constant">WHERE</span> users<span class="token punctuation">.</span>id <span class="token operator">=</span> <span class="token number">2</span> |
sql_tracker sẽ gộp chúng thành 1 câu query:
1 2 | <span class="token constant">SELECT</span> users<span class="token punctuation">.</span><span class="token operator">*</span> <span class="token constant">FROM</span> users <span class="token constant">WHERE</span> users<span class="token punctuation">.</span>id <span class="token operator">=</span> xxx |
sql_tracker sử dụng regular expressions để viết lại các câu SQL queries. Ví dụ như ở đây, nó đã tìm và thay thế các giá trị sau các operators so sánh như =, <>, >, < và cả BETWEEN … AND …
Sau khi đã nhóm lại, nó sẽ trở nên dễ dàng hơn để phân tích các câu queries, và tính toán tổng số query, thời gian trung bình, …
Storing
sql_tracker giữ tất cả các data trong bộ nhớ, và exports data trong 1 file JSON khi Rails process kết thúc. Tất cả các data chứa trong 1 Hash, format sẽ có dạng:
1 2 3 4 5 6 7 8 9 10 11 | <span class="token punctuation">{</span> key1<span class="token punctuation">:</span> <span class="token punctuation">{</span> sql<span class="token punctuation">:</span> <span class="token string">'SELECT users.* FROM users ...'</span><span class="token punctuation">,</span> count<span class="token punctuation">:</span> <span class="token number">1</span><span class="token punctuation">,</span> duration<span class="token punctuation">:</span> <span class="token number">0.34</span><span class="token punctuation">,</span> source<span class="token punctuation">:</span> <span class="token punctuation">[</span><span class="token string">'apps/model/user.rb:57:in ...'</span><span class="token punctuation">,</span> <span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">]</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> key2<span class="token punctuation">:</span> <span class="token punctuation">{</span> <span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span> <span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span> <span class="token punctuation">}</span> |
Khi các keys là md5 hoặc các câu sql queries đã được đơn giản hoá, và values là full câu sql query + một số thông tin thống kê.
Mặc định, file sẽ được lưu trong thư mục tmp trong Rails roots folder, ta cũng có thể thay đổi bằng config:
1 2 | <span class="token constant">SqlTracker</span><span class="token punctuation">:</span><span class="token punctuation">:</span><span class="token constant">Config</span><span class="token punctuation">.</span>output_path <span class="token operator">=</span> <span class="token builtin">File</span><span class="token punctuation">.</span>join<span class="token punctuation">(</span><span class="token constant">Rails</span><span class="token punctuation">.</span>root<span class="token punctuation">.</span>to_s<span class="token punctuation">,</span> <span class="token string">'my_folder'</span><span class="token punctuation">)</span> |
Nếu đã sử dụng app server puma, và set nhiều hơn 1 worker, ta sẽ thấy nhiền hơn 1 JSON output file trong output folder vì mỗi một worker sẽ track và lưu data riêng biệt.
Reporting
Cuối cùng, chúng ta có thể sinh ra report bằng cách sử dụng 1 hoặc nhiều JSON dump files:
1 2 | sql_tracker tmp<span class="token operator">/</span>sql_tracker<span class="token operator">-</span><span class="token operator">*</span><span class="token punctuation">.</span>json |
Report sẽ có dạng:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | <span class="token operator">===</span><span class="token operator">===</span><span class="token operator">===</span><span class="token operator">===</span><span class="token operator">===</span><span class="token operator">===</span><span class="token operator">===</span><span class="token operator">===</span><span class="token operator">===</span><span class="token operator">===</span><span class="token operator">===</span><span class="token operator">=</span> <span class="token constant">Total</span> <span class="token constant">Unique</span> <span class="token constant">SQL</span> <span class="token constant">Queries</span><span class="token punctuation">:</span> <span class="token number">24</span> <span class="token operator">===</span><span class="token operator">===</span><span class="token operator">===</span><span class="token operator">===</span><span class="token operator">===</span><span class="token operator">===</span><span class="token operator">===</span><span class="token operator">===</span><span class="token operator">===</span><span class="token operator">===</span><span class="token operator">===</span><span class="token operator">=</span> <span class="token constant">Count</span> <span class="token operator">|</span> <span class="token constant">Avg</span> <span class="token builtin">Time</span> <span class="token punctuation">(</span>ms<span class="token punctuation">)</span> <span class="token operator">|</span> <span class="token constant">SQL</span> <span class="token constant">Query</span> <span class="token operator">|</span> <span class="token constant">Source</span> <span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span> <span class="token number">8</span> <span class="token operator">|</span> <span class="token number">0.33</span> <span class="token operator">|</span> <span class="token constant">SELECT</span> `users`<span class="token punctuation">.</span><span class="token operator">*</span> <span class="token constant">FROM</span> `users` <span class="token constant">WHERE</span> `users`<span class="token punctuation">.</span>`id` <span class="token operator">=</span> xxx <span class="token constant">LIMIT</span> <span class="token number">1</span> <span class="token operator">|</span> app<span class="token operator">/</span>controllers<span class="token operator">/</span>users_controller<span class="token punctuation">.</span>rb<span class="token punctuation">:</span><span class="token number">125</span><span class="token symbol">:in</span> `create' <span class="token operator">|</span> <span class="token operator">|</span> <span class="token operator">|</span> app<span class="token operator">/</span>controllers<span class="token operator">/</span>projects_controller<span class="token punctuation">.</span>rb<span class="token punctuation">:</span><span class="token number">9</span><span class="token symbol">:in</span> `block <span class="token keyword">in</span> update' <span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span> <span class="token number">4</span> <span class="token operator">|</span> <span class="token number">0.27</span> <span class="token operator">|</span> <span class="token constant">SELECT</span> `projects`<span class="token punctuation">.</span><span class="token operator">*</span> <span class="token constant">FROM</span> `projects` <span class="token constant">WHERE</span> `projects`<span class="token punctuation">.</span>`user_id` <span class="token operator">=</span> xxx <span class="token constant">AND</span> `projects`<span class="token punctuation">.</span>`id` <span class="token operator">=</span> xxx <span class="token constant">LIMIT</span> <span class="token number">1</span> <span class="token operator">|</span> app<span class="token operator">/</span>controllers<span class="token operator">/</span>projects_controller<span class="token punctuation">.</span>rb<span class="token punctuation">:</span><span class="token number">4</span><span class="token symbol">:in</span> `update' <span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span> <span class="token number">2</span> <span class="token operator">|</span> <span class="token number">0.27</span> <span class="token operator">|</span> <span class="token constant">UPDATE</span> `projects` <span class="token constant">SET</span> `updated_at` <span class="token operator">=</span> xxx <span class="token constant">WHERE</span> `projects`<span class="token punctuation">.</span>`id` <span class="token operator">=</span> xxx <span class="token operator">|</span> app<span class="token operator">/</span>controllers<span class="token operator">/</span>projects_controller<span class="token punctuation">.</span>rb<span class="token punctuation">:</span><span class="token number">9</span><span class="token symbol">:in</span> `block <span class="token keyword">in</span> update' <span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span> <span class="token number">2</span> <span class="token operator">|</span> <span class="token number">1.76</span> <span class="token operator">|</span> <span class="token constant">SELECT</span> projects<span class="token punctuation">.</span><span class="token operator">*</span> <span class="token constant">FROM</span> projects <span class="token constant">WHERE</span> projects<span class="token punctuation">.</span>priority <span class="token constant">BETWEEN</span> xxx <span class="token constant">AND</span> xxx <span class="token constant">ORDER</span> <span class="token constant">BY</span> created_at <span class="token constant">DESC</span> <span class="token operator">|</span> app<span class="token operator">/</span>controllers<span class="token operator">/</span>projects_controller<span class="token punctuation">.</span>rb<span class="token punctuation">:</span><span class="token number">35</span><span class="token symbol">:in</span> `index' <span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span> <span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span> <span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span> |
Nó sẽ show cho ta tổng số lần gọi của từng câu truy vấn, thời gian trung bình của từng câu query, và dòng code nào gọi câu query đó. Từ report này, ta có thể hiểu được từng câu query đã được gọi nhưu thế nào, nơi nào gọi nó, … Nếu các câu query đơn giản được gọi quá nhiều lần, hãy nghĩ tới giải pháp cache nó lại. Và nếu cùng 1 câu query bị lặp lại ở nhiều nơi khác nhau trong source code, đó là lúc cần refactor lại code.
Thông thường, ta chọn một vài controller tests hoặc integration tests để chạy, và sau khi tests đã chạy xong, mở sql_tracker tmp/sql_tracker-*.json
lần nữa để dumped data và check lại các queries.
Kết luận
Như vậy bài viết đã tìm hiểu về tracking query trong rails với gem sql_tracker. Hy vọng bài viết giúp ích cho mọi người để có thể debug hoặc cải thiện lại chất lượng của Rails application của mình. Hẹn gặp lại!
Reference
https://github.com/steventen/sql_tracker
http://stevenyue.com/blogs/tracking-sql-queries-in-rails/.