tag:blogger.com,1999:blog-4937488729022245645.post-58049083795920312002008-07-06T21:52:00.005-05:002008-07-06T22:05:39.834-05:002008-07-06T22:05:39.834-05:00named scopes pwns will_paginate<style type="text/css">
/* Stylesheet generated from TextMate theme
*
* Mac Classic
*
*
*/
/* Mostly to improve view within the TextMate HTML viewer */
body {
margin: 0;
padding: 0;
}
pre.textmate-source {
margin: 0;
padding: 0 0 0 2px;
font-family: Monaco, monospace;
font-size: 11px;
line-height: 1.3em;
word-wrap: break-word;
white-space: pre;
white-space: pre-wrap;
white-space: -moz-pre-wrap;
white-space: -o-pre-wrap;
}
pre.textmate-source.mac_classic {
color: #000000;
background-color: #FFFFFF;
}
pre.textmate-source .linenum {
width: 75px;
padding: 0.1em 1em 0.2em 0;
color: #888;
background-color: #eee;
}
pre.textmate-source.mac_classic span {
padding-top: 0.2em;
padding-bottom: 0.1em;
}
pre.textmate-source.mac_classic ::selection {
background-color: rgba(77, 151, 255, 0.33);
}
/* Comment */
pre.textmate-source.mac_classic .comment {
color: #0066FF;
font-style: italic;
}
/* Keyword */
pre.textmate-source.mac_classic .keyword, pre.textmate-source.mac_classic .storage {
color: #0000FF;
font-weight: bold;
}
/* Number */
pre.textmate-source.mac_classic .constant_numeric {
color: #0000CD;
}
/* User-defined constant */
pre.textmate-source.mac_classic .constant {
color: #C5060B;
font-weight: bold;
}
/* Built-in constant */
pre.textmate-source.mac_classic .constant_language {
color: #585CF6;
font-weight: bold;
}
/* Variable */
pre.textmate-source.mac_classic .variable_language, pre.textmate-source.mac_classic .variable_other {
color: #318495;
}
/* String */
pre.textmate-source.mac_classic .string {
color: #036A07;
}
/* String interpolation */
pre.textmate-source.mac_classic .constant_character_escape, pre.textmate-source.mac_classic .string .source {
color: #26B31A;
}
/* Preprocessor line */
pre.textmate-source.mac_classic .meta_preprocessor {
color: #1A921C;
}
/* Preprocessor directive */
pre.textmate-source.mac_classic .keyword_control_import {
color: #0C450D;
font-weight: bold;
}
/* Function name */
pre.textmate-source.mac_classic .entity_name_function, pre.textmate-source.mac_classic .support_function_any-method {
color: #0000A2;
font-weight: bold;
}
/* Type name */
pre.textmate-source.mac_classic .entity_name_type {
text-decoration: underline;
}
/* Inherited class name */
pre.textmate-source.mac_classic .entity_other_inherited-class {
font-style: italic;
}
/* Function parameter */
pre.textmate-source.mac_classic .variable_parameter {
font-style: italic;
}
/* Function argument and result types */
pre.textmate-source.mac_classic .storage_type_method {
color: #70727E;
}
/* Section */
pre.textmate-source.mac_classic .meta_section .entity_name_section, pre.textmate-source.mac_classic .declaration_section .entity_name_section {
font-style: italic;
}
/* Library function */
pre.textmate-source.mac_classic .support_function {
color: #3C4C72;
font-weight: bold;
}
/* Library object */
pre.textmate-source.mac_classic .support_class, pre.textmate-source.mac_classic .support_type {
color: #6D79DE;
font-weight: bold;
}
/* Library constant */
pre.textmate-source.mac_classic .support_constant {
color: #06960E;
font-weight: bold;
}
/* Library variable */
pre.textmate-source.mac_classic .support_variable {
color: #21439C;
font-weight: bold;
}
/* JS: Operator */
pre.textmate-source.mac_classic .keyword_operator_js {
color: #687687;
}
/* Invalid */
pre.textmate-source.mac_classic .invalid {
color: #FFFFFF;
background-color: #990000;
}
/* Invalid trailing whitespace */
pre.textmate-source.mac_classic .invalid_deprecated_trailing-whitespace {
background-color: #FFD0D0;
}
/* Embedded source */
pre.textmate-source.mac_classic .text .source, pre.textmate-source.mac_classic .string_unquoted {
background-color: rgba(0, 0, 0, 0.05);
}
/* Embedded embedded source */
pre.textmate-source.mac_classic .text .source .string_unquoted, pre.textmate-source.mac_classic .text .source .text .source {
background-color: rgba(0, 0, 0, 0.06);
}
/* Markup XML declaration */
pre.textmate-source.mac_classic .meta_tag_preprocessor_xml {
color: #68685B;
}
/* Markup DOCTYPE */
pre.textmate-source.mac_classic .meta_tag_sgml_doctype, pre.textmate-source.mac_classic .meta_tag_sgml_doctype .entity, pre.textmate-source.mac_classic .meta_tag_sgml_doctype .string, pre.textmate-source.mac_classic .meta_tag_preprocessor_xml, pre.textmate-source.mac_classic .meta_tag_preprocessor_xml .entity, pre.textmate-source.mac_classic .meta_tag_preprocessor_xml .string {
color: #888888;
}
/* Markup DTD */
pre.textmate-source.mac_classic .string_quoted_docinfo_doctype_DTD {
font-style: italic;
}
/* Markup tag */
pre.textmate-source.mac_classic .meta_tag, pre.textmate-source.mac_classic .declaration_tag {
color: #1C02FF;
}
/* Markup name of tag */
pre.textmate-source.mac_classic .entity_name_tag {
font-weight: bold;
}
/* Markup tag attribute */
pre.textmate-source.mac_classic .entity_other_attribute-name {
font-style: italic;
}
/* Markup: Heading */
pre.textmate-source.mac_classic .markup_heading {
color: #0C07FF;
font-weight: bold;
}
/* Markup: Quote */
pre.textmate-source.mac_classic .markup_quote {
color: #000000;
font-style: italic;
}
/* Markup: List */
pre.textmate-source.mac_classic .markup_list {
color: #B90690;
}
</style>
<p><tt>will_paginate</tt> has its place. It's good for paginating when your queries are simple. My queries usually aren't simple, are yours? I noticed recently that one of my pages was taking a long time to display, around 1.9 seconds. I tracked it down to the <tt>will_paginate</tt>.</p>
<p>The problem is that <tt>will_paginate</tt> takes a single hash of ActiveRecord::Base#find arguments. That means if your query is really complex, then it's going to use that same complex query for both the result set and the count.</p>
<p>This is more or less what I was doing with <tt>will_paginate</tt> that it was choking on.</p>
<pre class="textmate-source mac_classic"><span class="source source_ruby source_ruby_rails"><span class="meta meta_rails meta_rails_model"><span class="meta meta_class meta_class_ruby"><span class="keyword keyword_control keyword_control_class keyword_control_class_ruby">class</span> <span class="entity entity_name entity_name_type entity_name_type_class entity_name_type_class_ruby">Post<span class="entity entity_other entity_other_inherited-class entity_other_inherited-class_ruby"> <span class="punctuation punctuation_separator punctuation_separator_inheritance punctuation_separator_inheritance_ruby"><</span> ActiveRecord::Base</span></span></span>
<span class="variable variable_other variable_other_constant variable_other_constant_ruby">STATUS_OK</span> <span class="keyword keyword_operator keyword_operator_assignment keyword_operator_assignment_ruby">=</span> <span class="constant constant_numeric constant_numeric_ruby">1</span>
<span class="support support_function support_function_activesupport support_function_activesupport_rails">cattr_accessor</span> <span class="constant constant_other constant_other_symbol constant_other_symbol_ruby"><span class="punctuation punctuation_definition punctuation_definition_constant punctuation_definition_constant_ruby">:</span>per_page</span>
per_page <span class="keyword keyword_operator keyword_operator_assignment keyword_operator_assignment_ruby">=</span> <span class="constant constant_numeric constant_numeric_ruby">15</span>
<span class="support support_function support_function_activerecord support_function_activerecord_rails">has_many</span> <span class="constant constant_other constant_other_symbol constant_other_symbol_ruby"><span class="punctuation punctuation_definition punctuation_definition_constant punctuation_definition_constant_ruby">:</span>watchers</span><span class="punctuation punctuation_separator punctuation_separator_object punctuation_separator_object_ruby">,</span> <span class="punctuation punctuation_separator punctuation_separator_method punctuation_separator_method_ruby">...</span>
</span><span class="keyword keyword_control keyword_control_ruby">end</span>
<span class="meta meta_rails meta_rails_controller"><span class="meta meta_class meta_class_ruby"><span class="keyword keyword_control keyword_control_class keyword_control_class_ruby">class</span> <span class="entity entity_name entity_name_type entity_name_type_class entity_name_type_class_ruby">PostsController<span class="entity entity_other entity_other_inherited-class entity_other_inherited-class_ruby"> <span class="punctuation punctuation_separator punctuation_separator_inheritance punctuation_separator_inheritance_ruby"><</span> ApplicationController</span></span></span>
<span class="meta meta_function meta_function_method meta_function_method_without-arguments meta_function_method_without-arguments_ruby"><span class="keyword keyword_control keyword_control_def keyword_control_def_ruby">def</span> <span class="entity entity_name entity_name_function entity_name_function_ruby">index</span></span>
page_no <span class="keyword keyword_operator keyword_operator_assignment keyword_operator_assignment_ruby">=</span> <span class="punctuation punctuation_section punctuation_section_function punctuation_section_function_ruby">(</span>params<span class="punctuation punctuation_section punctuation_section_array punctuation_section_array_ruby">[</span><span class="constant constant_other constant_other_symbol constant_other_symbol_ruby"><span class="punctuation punctuation_definition punctuation_definition_constant punctuation_definition_constant_ruby">:</span>page</span><span class="punctuation punctuation_section punctuation_section_array punctuation_section_array_ruby">]</span> <span class="keyword keyword_operator keyword_operator_logical keyword_operator_logical_ruby">&&</span> params<span class="punctuation punctuation_section punctuation_section_array punctuation_section_array_ruby">[</span><span class="constant constant_other constant_other_symbol constant_other_symbol_ruby"><span class="punctuation punctuation_definition punctuation_definition_constant punctuation_definition_constant_ruby">:</span>page</span><span class="punctuation punctuation_section punctuation_section_array punctuation_section_array_ruby">]</span><span class="punctuation punctuation_separator punctuation_separator_method punctuation_separator_method_ruby">.</span>to_i<span class="punctuation punctuation_section punctuation_section_function punctuation_section_function_ruby">)</span> <span class="keyword keyword_operator keyword_operator_logical keyword_operator_logical_ruby">||</span> <span class="constant constant_numeric constant_numeric_ruby">1</span>
<span class="variable variable_other variable_other_readwrite variable_other_readwrite_instance variable_other_readwrite_instance_ruby"><span class="punctuation punctuation_definition punctuation_definition_variable punctuation_definition_variable_ruby">@</span>posts</span> <span class="keyword keyword_operator keyword_operator_assignment keyword_operator_assignment_ruby">=</span> <span class="support support_class support_class_ruby">Post</span><span class="punctuation punctuation_separator punctuation_separator_method punctuation_separator_method_ruby">.</span>paginate <span class="constant constant_other constant_other_symbol constant_other_symbol_ruby"><span class="punctuation punctuation_definition punctuation_definition_constant punctuation_definition_constant_ruby">:</span>conditions</span> <span class="punctuation punctuation_separator punctuation_separator_key-value">=></span> <span class="punctuation punctuation_section punctuation_section_array punctuation_section_array_ruby">[</span><span class="string string_quoted string_quoted_double string_quoted_double_ruby"><span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_begin punctuation_definition_string_begin_ruby">"</span>posts.status_id = ?<span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_end punctuation_definition_string_end_ruby">"</span></span><span class="punctuation punctuation_separator punctuation_separator_object punctuation_separator_object_ruby">,</span> <span class="support support_class support_class_ruby">Post</span><span class="punctuation punctuation_separator punctuation_separator_other punctuation_separator_other_ruby">::</span><span class="variable variable_other variable_other_constant variable_other_constant_ruby">STATUS_OK</span><span class="punctuation punctuation_section punctuation_section_array punctuation_section_array_ruby">]</span><span class="punctuation punctuation_separator punctuation_separator_object punctuation_separator_object_ruby">,</span>
<span class="constant constant_other constant_other_symbol constant_other_symbol_ruby"><span class="punctuation punctuation_definition punctuation_definition_constant punctuation_definition_constant_ruby">:</span>order</span> <span class="punctuation punctuation_separator punctuation_separator_key-value">=></span> <span class="string string_quoted string_quoted_single string_quoted_single_ruby"><span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_begin punctuation_definition_string_begin_ruby">'</span>group_id DESC, checksum<span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_end punctuation_definition_string_end_ruby">'</span></span><span class="punctuation punctuation_separator punctuation_separator_object punctuation_separator_object_ruby">,</span> <span class="comment comment_line comment_line_number-sign comment_line_number-sign_ruby"><span class="punctuation punctuation_definition punctuation_definition_comment punctuation_definition_comment_ruby">#</span> don't ask, it's complicated
</span> <span class="constant constant_other constant_other_symbol constant_other_symbol_ruby"><span class="punctuation punctuation_definition punctuation_definition_constant punctuation_definition_constant_ruby">:</span>include</span> <span class="punctuation punctuation_separator punctuation_separator_key-value">=></span> <span class="constant constant_other constant_other_symbol constant_other_symbol_ruby"><span class="punctuation punctuation_definition punctuation_definition_constant punctuation_definition_constant_ruby">:</span>watchers</span><span class="punctuation punctuation_separator punctuation_separator_object punctuation_separator_object_ruby">,</span>
<span class="constant constant_other constant_other_symbol constant_other_symbol_ruby"><span class="punctuation punctuation_definition punctuation_definition_constant punctuation_definition_constant_ruby">:</span>page</span> <span class="punctuation punctuation_separator punctuation_separator_key-value">=></span> page_no
<span class="keyword keyword_control keyword_control_ruby">end</span>
</span><span class="keyword keyword_control keyword_control_ruby">end</span></span></pre>
<br/>
<p>The counting sql it makes out of that query does an outer join on <tt>watchers</tt> and selects distinct <tt>posts.id</tt>. Ouch. So the obvious solution is to simply do the count and result set queries ourselves. No biggie, but let's use named scopes to pretty things up.</p>
<pre class="textmate-source mac_classic"><span class="source source_ruby source_ruby_rails"><span class="meta meta_rails meta_rails_model"><span class="meta meta_class meta_class_ruby"><span class="keyword keyword_control keyword_control_class keyword_control_class_ruby">class</span> <span class="entity entity_name entity_name_type entity_name_type_class entity_name_type_class_ruby">Post<span class="entity entity_other entity_other_inherited-class entity_other_inherited-class_ruby"> <span class="punctuation punctuation_separator punctuation_separator_inheritance punctuation_separator_inheritance_ruby"><</span> ActiveRecord::Base</span></span></span>
<span class="variable variable_other variable_other_constant variable_other_constant_ruby">STATUS_OK</span> <span class="keyword keyword_operator keyword_operator_assignment keyword_operator_assignment_ruby">=</span> <span class="constant constant_numeric constant_numeric_ruby">1</span>
<span class="support support_function support_function_activesupport support_function_activesupport_rails">cattr_accessor</span> <span class="constant constant_other constant_other_symbol constant_other_symbol_ruby"><span class="punctuation punctuation_definition punctuation_definition_constant punctuation_definition_constant_ruby">:</span>per_page</span>
per_page <span class="keyword keyword_operator keyword_operator_assignment keyword_operator_assignment_ruby">=</span> <span class="constant constant_numeric constant_numeric_ruby">15</span>
<span class="support support_function support_function_activerecord support_function_activerecord_rails">has_many</span> <span class="constant constant_other constant_other_symbol constant_other_symbol_ruby"><span class="punctuation punctuation_definition punctuation_definition_constant punctuation_definition_constant_ruby">:</span>watchers</span><span class="punctuation punctuation_separator punctuation_separator_object punctuation_separator_object_ruby">,</span> <span class="punctuation punctuation_separator punctuation_separator_method punctuation_separator_method_ruby">...</span>
named_scope <span class="constant constant_other constant_other_symbol constant_other_symbol_ruby"><span class="punctuation punctuation_definition punctuation_definition_constant punctuation_definition_constant_ruby">:</span>ok</span><span class="punctuation punctuation_separator punctuation_separator_object punctuation_separator_object_ruby">,</span> <span class="constant constant_other constant_other_symbol constant_other_symbol_ruby"><span class="punctuation punctuation_definition punctuation_definition_constant punctuation_definition_constant_ruby">:</span>conditions</span> <span class="punctuation punctuation_separator punctuation_separator_key-value">=></span> <span class="punctuation punctuation_section punctuation_section_scope punctuation_section_scope_ruby">{</span><span class="string string_quoted string_quoted_double string_quoted_double_ruby"><span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_begin punctuation_definition_string_begin_ruby">"</span>posts.status_id<span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_end punctuation_definition_string_end_ruby">"</span></span> <span class="punctuation punctuation_separator punctuation_separator_key-value">=></span> <span class="support support_class support_class_ruby">Post</span><span class="punctuation punctuation_separator punctuation_separator_other punctuation_separator_other_ruby">::</span><span class="variable variable_other variable_other_constant variable_other_constant_ruby">STATUS_OK</span><span class="punctuation punctuation_section punctuation_section_scope punctuation_section_scope_ruby">}</span>
named_scope <span class="constant constant_other constant_other_symbol constant_other_symbol_ruby"><span class="punctuation punctuation_definition punctuation_definition_constant punctuation_definition_constant_ruby">:</span>recent</span><span class="punctuation punctuation_separator punctuation_separator_object punctuation_separator_object_ruby">,</span> <span class="constant constant_other constant_other_symbol constant_other_symbol_ruby"><span class="punctuation punctuation_definition punctuation_definition_constant punctuation_definition_constant_ruby">:</span>order</span> <span class="punctuation punctuation_separator punctuation_separator_key-value">=></span> <span class="string string_quoted string_quoted_double string_quoted_double_ruby"><span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_begin punctuation_definition_string_begin_ruby">"</span>group_id DESC, checksum<span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_end punctuation_definition_string_end_ruby">"</span></span>
named_scope <span class="constant constant_other constant_other_symbol constant_other_symbol_ruby"><span class="punctuation punctuation_definition punctuation_definition_constant punctuation_definition_constant_ruby">:</span>paginate</span><span class="punctuation punctuation_separator punctuation_separator_object punctuation_separator_object_ruby">,</span> lambda <span class="punctuation punctuation_section punctuation_section_scope punctuation_section_scope_ruby">{</span><span class="meta meta_syntax meta_syntax_ruby meta_syntax_ruby_start-block"> </span><span class="punctuation punctuation_separator punctuation_separator_variable punctuation_separator_variable_ruby">|</span><span class="variable variable_other variable_other_block variable_other_block_ruby">page_no</span><span class="punctuation punctuation_separator punctuation_separator_variable punctuation_separator_variable_ruby">|</span> <span class="punctuation punctuation_section punctuation_section_scope punctuation_section_scope_ruby">{</span><span class="constant constant_other constant_other_symbol constant_other_symbol_ruby"><span class="punctuation punctuation_definition punctuation_definition_constant punctuation_definition_constant_ruby">:</span>offset</span> <span class="punctuation punctuation_separator punctuation_separator_key-value">=></span> <span class="punctuation punctuation_section punctuation_section_scope punctuation_section_scope_ruby">{</span><span class="punctuation punctuation_section punctuation_section_function punctuation_section_function_ruby">(</span>page_no<span class="keyword keyword_operator keyword_operator_arithmetic keyword_operator_arithmetic_ruby">-</span><span class="constant constant_numeric constant_numeric_ruby">1</span><span class="punctuation punctuation_section punctuation_section_function punctuation_section_function_ruby">)</span><span class="keyword keyword_operator keyword_operator_arithmetic keyword_operator_arithmetic_ruby">*</span>per_page<span class="punctuation punctuation_section punctuation_section_scope punctuation_section_scope_ruby">}</span><span class="punctuation punctuation_separator punctuation_separator_object punctuation_separator_object_ruby">,</span> <span class="constant constant_other constant_other_symbol constant_other_symbol_ruby"><span class="punctuation punctuation_definition punctuation_definition_constant punctuation_definition_constant_ruby">:</span>limit</span> <span class="punctuation punctuation_separator punctuation_separator_key-value">=></span> per_page<span class="punctuation punctuation_section punctuation_section_scope punctuation_section_scope_ruby">}</span> <span class="punctuation punctuation_section punctuation_section_scope punctuation_section_scope_ruby">}</span>
</span><span class="keyword keyword_control keyword_control_ruby">end</span>
<span class="meta meta_rails meta_rails_controller"><span class="meta meta_class meta_class_ruby"><span class="keyword keyword_control keyword_control_class keyword_control_class_ruby">class</span> <span class="entity entity_name entity_name_type entity_name_type_class entity_name_type_class_ruby">PostsController<span class="entity entity_other entity_other_inherited-class entity_other_inherited-class_ruby"> <span class="punctuation punctuation_separator punctuation_separator_inheritance punctuation_separator_inheritance_ruby"><</span> ApplicationController</span></span></span>
<span class="meta meta_function meta_function_method meta_function_method_without-arguments meta_function_method_without-arguments_ruby"><span class="keyword keyword_control keyword_control_def keyword_control_def_ruby">def</span> <span class="entity entity_name entity_name_function entity_name_function_ruby">index</span></span>
page_no <span class="keyword keyword_operator keyword_operator_assignment keyword_operator_assignment_ruby">=</span> <span class="punctuation punctuation_section punctuation_section_function punctuation_section_function_ruby">(</span>params<span class="punctuation punctuation_section punctuation_section_array punctuation_section_array_ruby">[</span><span class="constant constant_other constant_other_symbol constant_other_symbol_ruby"><span class="punctuation punctuation_definition punctuation_definition_constant punctuation_definition_constant_ruby">:</span>page</span><span class="punctuation punctuation_section punctuation_section_array punctuation_section_array_ruby">]</span> <span class="keyword keyword_operator keyword_operator_logical keyword_operator_logical_ruby">&&</span> params<span class="punctuation punctuation_section punctuation_section_array punctuation_section_array_ruby">[</span><span class="constant constant_other constant_other_symbol constant_other_symbol_ruby"><span class="punctuation punctuation_definition punctuation_definition_constant punctuation_definition_constant_ruby">:</span>page</span><span class="punctuation punctuation_section punctuation_section_array punctuation_section_array_ruby">]</span><span class="punctuation punctuation_separator punctuation_separator_method punctuation_separator_method_ruby">.</span>to_i<span class="punctuation punctuation_section punctuation_section_function punctuation_section_function_ruby">)</span> <span class="keyword keyword_operator keyword_operator_logical keyword_operator_logical_ruby">||</span> <span class="constant constant_numeric constant_numeric_ruby">1</span>
<span class="variable variable_other variable_other_readwrite variable_other_readwrite_instance variable_other_readwrite_instance_ruby"><span class="punctuation punctuation_definition punctuation_definition_variable punctuation_definition_variable_ruby">@</span>posts</span> <span class="keyword keyword_operator keyword_operator_assignment keyword_operator_assignment_ruby">=</span> <span class="support support_class support_class_ruby">Post</span><span class="punctuation punctuation_separator punctuation_separator_method punctuation_separator_method_ruby">.</span>ok<span class="punctuation punctuation_separator punctuation_separator_method punctuation_separator_method_ruby">.</span>recent<span class="punctuation punctuation_separator punctuation_separator_method punctuation_separator_method_ruby">.</span>paginate<span class="punctuation punctuation_section punctuation_section_function punctuation_section_function_ruby">(</span>page_no<span class="punctuation punctuation_section punctuation_section_function punctuation_section_function_ruby">)</span><span class="punctuation punctuation_separator punctuation_separator_method punctuation_separator_method_ruby">.</span>all<span class="punctuation punctuation_section punctuation_section_function punctuation_section_function_ruby">(</span><span class="constant constant_other constant_other_symbol constant_other_symbol_ruby"><span class="punctuation punctuation_definition punctuation_definition_constant punctuation_definition_constant_ruby">:</span>include</span> <span class="punctuation punctuation_separator punctuation_separator_key-value">=></span> <span class="constant constant_other constant_other_symbol constant_other_symbol_ruby"><span class="punctuation punctuation_definition punctuation_definition_constant punctuation_definition_constant_ruby">:</span>watchers</span><span class="punctuation punctuation_section punctuation_section_function punctuation_section_function_ruby">)</span>
<span class="variable variable_other variable_other_readwrite variable_other_readwrite_instance variable_other_readwrite_instance_ruby"><span class="punctuation punctuation_definition punctuation_definition_variable punctuation_definition_variable_ruby">@</span>post_count</span> <span class="keyword keyword_operator keyword_operator_assignment keyword_operator_assignment_ruby">=</span> <span class="support support_class support_class_ruby">Post</span><span class="punctuation punctuation_separator punctuation_separator_method punctuation_separator_method_ruby">.</span>ok<span class="punctuation punctuation_separator punctuation_separator_method punctuation_separator_method_ruby">.</span>count
<span class="keyword keyword_control keyword_control_ruby">end</span>
</span><span class="keyword keyword_control keyword_control_ruby">end</span></span></pre>
<br/>
<p>Pretty slick... and since we're doing the pagination "explicitly", we know that the counting is as simple as it needs to be. Let's take a look at the benchmarks, before and after.</p>
<pre class="textmate-source mac_classic"><span class="source source_sql source_sql_ruby"><span class="comment comment_line comment_line_number-sign comment_line_number-sign_sql"><span class="punctuation punctuation_definition punctuation_definition_comment punctuation_definition_comment_sql">#</span> The SQL calls generated by will_paginate
</span>Post Load (<span class="constant constant_numeric constant_numeric_sql">0</span>.<span class="constant constant_numeric constant_numeric_sql">341523</span>)
<span class="keyword keyword_other keyword_other_DML keyword_other_DML_sql">SELECT</span> <span class="keyword keyword_operator keyword_operator_star keyword_operator_star_sql">*</span> <span class="keyword keyword_other keyword_other_DML keyword_other_DML_sql">FROM</span> <span class="string string_quoted string_quoted_double string_quoted_double_sql"><span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_begin punctuation_definition_string_begin_sql">"</span>posts"</span> <span class="keyword keyword_other keyword_other_DML keyword_other_DML_sql">WHERE</span> (<span class="constant constant_other constant_other_database-name constant_other_database-name_sql">post</span>.<span class="constant constant_other constant_other_table-name constant_other_table-name_sql">status_id</span> <span class="keyword keyword_operator keyword_operator_comparison keyword_operator_comparison_sql">=</span> <span class="constant constant_numeric constant_numeric_sql">1</span>) <span class="keyword keyword_other keyword_other_DML keyword_other_DML_sql">ORDER BY</span> group_id <span class="keyword keyword_other keyword_other_order keyword_other_order_sql">DESC</span>, checksum <span class="keyword keyword_other keyword_other_DML keyword_other_DML_sql">LIMIT</span> <span class="constant constant_numeric constant_numeric_sql">15</span> OFFSET <span class="constant constant_numeric constant_numeric_sql">0</span>
Watcher Load (<span class="constant constant_numeric constant_numeric_sql">0</span>.<span class="constant constant_numeric constant_numeric_sql">005799</span>)
<span class="keyword keyword_other keyword_other_DML keyword_other_DML_sql">SELECT</span> <span class="string string_quoted string_quoted_double string_quoted_double_sql"><span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_begin punctuation_definition_string_begin_sql">"</span>watchers"</span>.<span class="keyword keyword_operator keyword_operator_star keyword_operator_star_sql">*</span> <span class="keyword keyword_other keyword_other_DML keyword_other_DML_sql">FROM</span> <span class="string string_quoted string_quoted_double string_quoted_double_sql"><span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_begin punctuation_definition_string_begin_sql">"</span>watchers"</span> <span class="keyword keyword_other keyword_other_DML keyword_other_DML_sql">WHERE</span> (<span class="string string_quoted string_quoted_double string_quoted_double_sql"><span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_begin punctuation_definition_string_begin_sql">"</span>watchers"</span>.page_id <span class="keyword keyword_other keyword_other_data-integrity keyword_other_data-integrity_sql">IN</span> (...)) <span class="keyword keyword_other keyword_other_DML keyword_other_DML_sql">ORDER BY</span> id
SQL (<span class="constant constant_numeric constant_numeric_sql">1</span>.<span class="constant constant_numeric constant_numeric_sql">335042</span>)
<span class="keyword keyword_other keyword_other_DML keyword_other_DML_sql">SELECT</span> <span class="support support_function support_function_aggregate support_function_aggregate_sql">count</span>(DISTINCT <span class="string string_quoted string_quoted_double string_quoted_double_sql"><span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_begin punctuation_definition_string_begin_sql">"</span>posts"</span>.id) <span class="keyword keyword_other keyword_other_alias keyword_other_alias_sql">AS</span> count_all <span class="keyword keyword_other keyword_other_DML keyword_other_DML_sql">FROM</span> <span class="string string_quoted string_quoted_double string_quoted_double_sql"><span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_begin punctuation_definition_string_begin_sql">"</span>posts"</span> <span class="keyword keyword_other keyword_other_DML keyword_other_DML_sql">LEFT OUTER JOIN</span> <span class="string string_quoted string_quoted_double string_quoted_double_sql"><span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_begin punctuation_definition_string_begin_sql">"</span>watchers"</span> <span class="keyword keyword_other keyword_other_DDL keyword_other_DDL_create keyword_other_DDL_create_II keyword_other_DDL_create_II_sql">ON</span> <span class="constant constant_other constant_other_database-name constant_other_database-name_sql">watchers</span>.<span class="constant constant_other constant_other_table-name constant_other_table-name_sql">post_id</span> <span class="keyword keyword_operator keyword_operator_comparison keyword_operator_comparison_sql">=</span> <span class="constant constant_other constant_other_database-name constant_other_database-name_sql">posts</span>.<span class="constant constant_other constant_other_table-name constant_other_table-name_sql">id</span> <span class="keyword keyword_other keyword_other_DML keyword_other_DML_sql">WHERE</span> (<span class="constant constant_other constant_other_database-name constant_other_database-name_sql">posts</span>.<span class="constant constant_other constant_other_table-name constant_other_table-name_sql">status_id</span> <span class="keyword keyword_operator keyword_operator_comparison keyword_operator_comparison_sql">=</span> <span class="constant constant_numeric constant_numeric_sql">1</span>)
<span class="comment comment_line comment_line_number-sign comment_line_number-sign_sql"><span class="punctuation punctuation_definition punctuation_definition_comment punctuation_definition_comment_sql">#</span> The SQL calls generated when we "manually paginate".
</span>Post Load (<span class="constant constant_numeric constant_numeric_sql">0</span>.<span class="constant constant_numeric constant_numeric_sql">350336</span>)
<span class="keyword keyword_other keyword_other_DML keyword_other_DML_sql">SELECT</span> <span class="keyword keyword_operator keyword_operator_star keyword_operator_star_sql">*</span> <span class="keyword keyword_other keyword_other_DML keyword_other_DML_sql">FROM</span> <span class="string string_quoted string_quoted_double string_quoted_double_sql"><span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_begin punctuation_definition_string_begin_sql">"</span>posts"</span> <span class="keyword keyword_other keyword_other_DML keyword_other_DML_sql">WHERE</span> (<span class="string string_quoted string_quoted_double string_quoted_double_sql"><span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_begin punctuation_definition_string_begin_sql">"</span>posts"</span>.<span class="string string_quoted string_quoted_double string_quoted_double_sql"><span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_begin punctuation_definition_string_begin_sql">"</span>status_id"</span> <span class="keyword keyword_operator keyword_operator_comparison keyword_operator_comparison_sql">=</span> <span class="constant constant_numeric constant_numeric_sql">1</span>) <span class="keyword keyword_other keyword_other_DML keyword_other_DML_sql">ORDER BY</span> group_id <span class="keyword keyword_other keyword_other_order keyword_other_order_sql">DESC</span>, checksum <span class="keyword keyword_other keyword_other_DML keyword_other_DML_sql">LIMIT</span> <span class="constant constant_numeric constant_numeric_sql">15</span> OFFSET <span class="constant constant_numeric constant_numeric_sql">0</span>
Watcher Load (<span class="constant constant_numeric constant_numeric_sql">0</span>.<span class="constant constant_numeric constant_numeric_sql">004582</span>)
<span class="keyword keyword_other keyword_other_DML keyword_other_DML_sql">SELECT</span> <span class="string string_quoted string_quoted_double string_quoted_double_sql"><span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_begin punctuation_definition_string_begin_sql">"</span>watchers"</span>.<span class="keyword keyword_operator keyword_operator_star keyword_operator_star_sql">*</span> <span class="keyword keyword_other keyword_other_DML keyword_other_DML_sql">FROM</span> <span class="string string_quoted string_quoted_double string_quoted_double_sql"><span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_begin punctuation_definition_string_begin_sql">"</span>watchers"</span> <span class="keyword keyword_other keyword_other_DML keyword_other_DML_sql">WHERE</span> (<span class="string string_quoted string_quoted_double string_quoted_double_sql"><span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_begin punctuation_definition_string_begin_sql">"</span>watchers"</span>.post_id <span class="keyword keyword_other keyword_other_data-integrity keyword_other_data-integrity_sql">IN</span> (...)) <span class="keyword keyword_other keyword_other_DML keyword_other_DML_sql">ORDER BY</span> id
SQL (<span class="constant constant_numeric constant_numeric_sql">0</span>.<span class="constant constant_numeric constant_numeric_sql">023346</span>)
<span class="keyword keyword_other keyword_other_DML keyword_other_DML_sql">SELECT</span> <span class="support support_function support_function_aggregate support_function_aggregate_sql">count</span>(<span class="keyword keyword_operator keyword_operator_star keyword_operator_star_sql">*</span>) <span class="keyword keyword_other keyword_other_alias keyword_other_alias_sql">AS</span> count_all <span class="keyword keyword_other keyword_other_DML keyword_other_DML_sql">FROM</span> <span class="string string_quoted string_quoted_double string_quoted_double_sql"><span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_begin punctuation_definition_string_begin_sql">"</span>posts"</span> <span class="keyword keyword_other keyword_other_DML keyword_other_DML_sql">WHERE</span> (<span class="string string_quoted string_quoted_double string_quoted_double_sql"><span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_begin punctuation_definition_string_begin_sql">"</span>posts"</span>.<span class="string string_quoted string_quoted_double string_quoted_double_sql"><span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_begin punctuation_definition_string_begin_sql">"</span>status_id"</span> <span class="keyword keyword_operator keyword_operator_comparison keyword_operator_comparison_sql">=</span> <span class="constant constant_numeric constant_numeric_sql">1</span>)</span></pre>
<br/>
<p>We save roughly 1.3 seconds by intelligently doing the counting. I really don't think using <tt>will_paginate</tt> buys you any cleaner code over using named scopes. Now all you have to do is implement a method similar to the <tt>will_paginate</tt> view helper and you can remove <tt>will_paginate</tt> from your project.</p>Christopher J. Bottarohttp://www.blogger.com/profile/14116593743589959438noreply@blogger.com