Class: PgCanary::Rules::OrderByRandom

Inherits:
Base
  • Object
show all
Defined in:
lib/pg_canary/rules/definitions/order_by_random.rb

Overview

ORDER BY RANDOM() sorts the entire result set just to pick rows — always suspicious regardless of table size.

Constant Summary

Constants included from PgQuerySupport

PgQuerySupport::COMPARISON_OPS

Instance Method Summary collapse

Methods inherited from Base

all, #enabled?, options, rule_name

Instance Method Details

#check(query) ⇒ Object



12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
# File 'lib/pg_canary/rules/definitions/order_by_random.rb', line 12

def check(query)
  detections = []
  query.each_scope do |scope|
    scope.sort_items.each do |sort_by|
      func = unwrap_node(sort_by.node)
      next unless func.is_a?(PgQuery::FuncCall)
      next unless function_name(func) == "random"

      detections << detection(
        query,
        table: scope.tables.length == 1 ? scope.tables.first : nil,
        message: "ORDER BY RANDOM() reads and sorts every row, so it gets slower " \
                 "in proportion to table size.",
        suggestion: <<~SUGGESTION.chomp
          Alternatives:
            - TABLESAMPLE: SELECT * FROM t TABLESAMPLE SYSTEM (1) LIMIT n
            - random primary-key range: WHERE id >= (SELECT (random() * max(id))::bigint FROM t) LIMIT n
        SUGGESTION
      )
    end
  end
  detections
end

#default_enabledObject



8
9
10
# File 'lib/pg_canary/rules/definitions/order_by_random.rb', line 8

def default_enabled
  true
end