2016-08-09 4 views
0

현재 내 앱에 약 1280 만 개의 행이있는 테이블이 있고이 테이블의 각 행에 1280 만 개의 행이있는 다른 5 개의 테이블과의 연결은 has_one입니다.레일스의 데이터베이스 쿼리 속도가 매우 느림

그런 다음이 모든 데이터는 filterrific 보석을 사용하여 필터링 기능이있는 테이블에 표시됩니다. 문제는 열 특정 검색과 같은 쿼리를 수행하는 데 너무 많은 시간이 걸리는 반면 Table.count 쿼리는 완료하는 데 약 30-40 초가 걸리는 것입니다. 쿼리 시간을 크게 줄일 수있는 쿼리 최적화 방법이 있습니까?

나는 열심히로드를 구현하고 표시하는 데 필요한 열만 선택했지만 성능 향상은 중요하지 않았습니다.

예 스키마 :

검색 필터
create_table "domains", force: :cascade do |t| 
    t.string "name",          null: false 
    t.integer "age",      default: 0 
    t.integer "pr",      default: 0 
    t.boolean "dmoz",      default: false 
    t.float "price",     default: 0.0 
    t.string "listing_type" 
    t.datetime "created_at",        null: false 
    t.datetime "updated_at",        null: false 
    t.string "source" 
    t.datetime "end_date_time" 
    t.integer "no_bids",     default: 0 
    t.float "traffic",     default: 0.0 
    t.float "valuation",    default: 0.0 
    end 
add_index "domains", ["name"], name: "index_domains_on_name", unique: true, using: :btree 

은 범위가 사용되는 domain.rb 아래 예 :

scope :basic, lambda { |basic| 
    query = "" 
    query += "age BETWEEN #{check_min(basic.age_min.to_i)} AND #{check_max(basic.age_max.to_i)} " if basic.age_min.present? || basic.age_max.present? 
    query += "AND price BETWEEN #{check_min(basic.price_min.to_f)} AND #{check_max(basic.price_max.to_f)} " if basic.price_min.present? || basic.price_max.present? 
    query += "AND pr BETWEEN #{check_min(basic.pr_min.to_i)} AND #{check_max(basic.pr_max.to_i)} " if basic.pr_min.present? || basic.pr_max.present? 
    if query[0..2] == 'AND' 
     query = query[3..-1] 
    end 

    where(query) 
    } 
+0

스키마 및 스키마 검색 방법에 대한 자세한 정보를 제공 할 수 있습니까? 더/더 나은 색인이 필요하지만 더 자세한 정보가 없으면 속도를 높이는 것이 어렵습니다. – rdubya

+0

최적화를 원한다고 계산합니까? 주어진 테이블의 크기는 카운트에 충분한 대략적인 값입니까? –

+0

안녕 얘들 아, 방금 추가 세부 사항을 추가했습니다. 가능한 경우 카운트 및 쿼리 속도를 높이고 싶습니다. @ChrisTravers는 시간을 크게 줄이면 대략적인 값이면 충분합니다. 방법으로 대략적인 값을 얻으려면 어떻게해야합니까? –

답변

0

은 대략 행 수를 얻으려면, SQL에서는 다음과 같이한다.

SELECT reltuples AS approximate_row_count 
    FROM pg_class WHERE relname = 'domains'; 

생성 된 SQL 또는 쿼리 계획을 제공하지 않았으므로 여기에 대한 일반적인 조언이 제공됩니다. 더 많은 정보가 들어올 때 좀 더 구체적인 조언을 추가 할 수는 있지만 다소 제한적입니다.

SQL은 선언적 언어입니다. 즉, 우리가 원하는 것을 db에 알려주고 빨리 처리 할 수 ​​있는지 확인하려고합니다. 그래서 당신이하고 싶은 것은 느린 문장 (postgresql.conf에 log_min_duration_statement)을 기록한 다음 그 문장을 분석하는 것입니다. 쿼리 계획이 없으면 어떤 인덱스가 필요한지 알기가 매우 어렵습니다.

쿼리 계획은 기본적으로 PostgreSQL이 사용할 수있는 인덱스를 사용하여 원하는 데이터를 검색하는 가장 빠른 방법이라고 판단한 것을 알려줍니다. 여기서 큰 테이블에 대한 순차적 스캔을 예기치 않게 수행하는 경우 (예 : 순차 스캔은 일반적으로 더 빠르지 만, 대부분의 행을 잘라내는 방법) 선택적 인덱스를 살펴보고 해당 필드를 인덱싱하려는 경우 10 % 테이블의).

관련 문제