เมื่อใดควรเพิ่มดัชนีใดในตารางใน Rails


134

ฉันมีคำถามเกี่ยวกับฐานข้อมูล Rails

  • ฉันควรเพิ่ม "ดัชนี" ให้กับคีย์ต่างประเทศทั้งหมดเช่น "xxx_id" หรือไม่
  • ฉันควรเพิ่ม "ดัชนี" ในคอลัมน์ "id" ที่สร้างขึ้นโดยอัตโนมัติหรือไม่
  • ฉันควรเพิ่ม "ดัชนี (ไม่ซ้ำกัน)" ในคอลัมน์ "id" ที่สร้างขึ้นโดยอัตโนมัติหรือไม่

  • หากฉันเพิ่มดัชนีให้กับคีย์ต่างประเทศสองรายการพร้อมกัน ( add_index (:users, [:category, :state_id])จะเกิดอะไรขึ้นสิ่งนี้แตกต่างจากการเพิ่มดัชนีสำหรับแต่ละคีย์อย่างไร

    class CreateUsers < ActiveRecord::Migration
      def self.up
        create_table :users do |t|
          t.string :name
          t.integer :category_id 
          t.integer :state_id
          t.string :email
          t.boolean :activated
          t.timestamps
        end
      # Do I need this? Is it meaningless to add the index to the primary key?
      # If so, do I need :unique => true ?
      add_index :users, :id 
      # I don't think I need ":unique => true here", right?
      add_index :users, :category_id # Should I need this?
      add_index :users, :state_id # Should I need this?
      # Are the above the same as the following?
      add_index (:users, [:category, :state_id])
      end
    end
    

คำตอบที่ดีจนถึงตอนนี้ คำถามเพิ่มเติม

  • ฉันควรเพิ่ม "index with unique" สำหรับ xxx_id ใช่ไหม

คำตอบ:


176

ฉันควรเพิ่ม "ดัชนี" ให้กับคีย์ต่างประเทศทั้งหมดเช่น "xxx_id" หรือไม่

มันจะดีกว่าเพราะมันช่วยเร่งการค้นหาในการเรียงลำดับในคอลัมน์นี้ และคีย์ต่างประเทศเป็นสิ่งที่ถูกค้นหามาก

ตั้งแต่รุ่นที่ 5 ของรางดัชนีจะถูกสร้างขึ้นโดยอัตโนมัติสำหรับข้อมูลเพิ่มเติมโปรดดูที่นี่

ฉันควรเพิ่ม "ดัชนี" ในคอลัมน์ "id" ที่สร้างขึ้นโดยอัตโนมัติหรือไม่

ไม่นี่ทำโดยรางแล้ว

ฉันควรเพิ่ม "ดัชนี (ไม่ซ้ำกัน)" ในคอลัมน์ "id" ที่สร้างขึ้นโดยอัตโนมัติหรือไม่

ไม่เหมือนข้างบน

หากฉันเพิ่มดัชนีให้กับคีย์ต่างประเทศสองรายการพร้อมกัน ( add_index (:users, [:category_id, :state_id])จะเกิดอะไรขึ้นสิ่งนี้แตกต่างจากการเพิ่มดัชนีสำหรับแต่ละคีย์อย่างไร

จากนั้นดัชนีคือดัชนีรวมของสองคอลัมน์ แต่นั่นไม่ได้ทำให้ความรู้สึกใด ๆ ถ้าคุณต้องการทุกรายการหนึ่งcategory_id และหนึ่งstate_id(มันควรจะเป็นcategory_idไม่ได้category) ในเวลาเดียวกัน

ดัชนีเช่นนี้จะเร่งการร้องขอต่อไปนี้:

# rails 2
User.find(:all, :conditions => { :state_id => some_id, :category_id => some_other_id })

# rails 3
User.where(:state_id => some_id, :category_id => some_other_id)

ที่ไหน

add_index :users, :category_id
add_index :users, :state_id

จะเร่งความเร็วตามคำขอเหล่านี้:

# rails 2+3
User.find_by_category_id(some_id)
User.find_by_state_id(some_other_id)

# or
# rails 2
User.find(:all, :conditions => {:category_id => some_id})
User.find(:all, :conditions => {:state_id => some_other_id})

# rails 3
User.where(:category_id => some_id)
User.where(:state_id => some_other_id)

ฉันควรเพิ่ม "index with unique" สำหรับ xxx_id ใช่ไหม

ไม่เพราะหากคุณทำเช่นนี้ผู้ใช้เพียงคนเดียวสามารถอยู่ในหมวดหมู่เดียวได้ แต่ความหมายของหมวดหมู่คือคุณสามารถรวมผู้ใช้จำนวนมากไว้ในหมวดหมู่เดียว ของคุณในUserรูปแบบที่คุณมีบางสิ่งบางอย่างเช่นนี้และในบางสิ่งบางอย่างประเภทรูปแบบของคุณเช่นbelongs_to :category has_many :usersหากคุณมีhas_manyความสัมพันธ์foreign_keyฟิลด์จะต้องไม่ซ้ำกัน!

สำหรับรายละเอียดเพิ่มเติมเกี่ยวกับเรื่องนี้คุณควรจะดูที่Tadman 's ดีคำตอบ


3
คำตอบที่ดี คำถามเพิ่มเติม ฉันควรเพิ่ม "index with unique" สำหรับ xxx_id ใช่ไหม
TK.

คำถามคุณจะจัดทำดัชนีคีย์ต่างประเทศหรือไม่หากช่องนั้นไม่ค่อยมีการค้นหาอย่างชัดเจน
Noz

@Cyle ฉันตอบไม่ได้แน่นอนขึ้นอยู่กับเครื่องของคุณขนาดของฐานข้อมูลและลักษณะการสืบค้นของคุณ หากแบบสอบถามมาจากเว็บฉันอาจจะตอบว่าใช่เพราะการตอบกลับที่รวดเร็วจะดีกว่าเสมอหากเป็นงานเบื้องหลังและคุณต้องการประหยัดเนื้อที่ดิสก์คุณไม่จำเป็นต้องตั้งค่า แต่ถ้าเนื้อที่ดิสก์ ไม่ใช่ปัญหาฉันจะเพิ่มดัชนีอยู่ดี
jigfox

113

การจัดทำดัชนีอาจเป็นเรื่องที่ยุ่งยากและละเอียดอ่อน แต่มีกฎทั่วไปที่ใช้ซึ่งสามารถทำให้การพิจารณาว่าจะใช้อะไรได้ง่ายขึ้นมาก

สิ่งแรกที่ต้องจำไว้คือดัชนีสามารถทำงานได้มากกว่าหนึ่งวิธี ดัชนีบน A, B, C ยังใช้ได้กับ A, B และ A ดังนั้นคุณสามารถออกแบบดัชนีของคุณให้ใช้งานได้หลากหลายมากขึ้นหากคุณเรียงลำดับอย่างถูกต้อง สมุดโทรศัพท์ได้รับการจัดทำดัชนีตามนามสกุล, ชื่อดังนั้นคุณสามารถค้นหาผู้คนได้อย่างง่ายดายจากนามสกุลของพวกเขาหรือใช้นามสกุลและชื่อผสมกัน อย่างไรก็ตามคุณไม่สามารถค้นหาได้โดยตรงจากชื่อของพวกเขา คุณต้องมีดัชนีแยกต่างหากสำหรับสิ่งนั้น เช่นเดียวกับหมายเลขโทรศัพท์ซึ่งคุณจะต้องจัดทำดัชนีด้วย

ด้วยเหตุนี้จึงมีหลายสิ่งที่จะกำหนดวิธีการสร้างดัชนี:

  • หากคุณมีbelongs_to- การhas_manyจับคู่ความสัมพันธ์คุณจะต้องมีดัชนีสำหรับคีย์ต่างประเทศที่ใช้
  • หากคุณสั่งซื้อระเบียนของคุณและมีจำนวนมากที่จะถูกแบ่งหน้าคุณควรเพิ่มคอลัมน์คำสั่งนั้นที่ส่วนท้ายของดัชนี
  • หากคุณมีhas_many :throughความสัมพันธ์ตารางการเข้าร่วมของคุณควรมีดัชนีเฉพาะสำหรับคุณสมบัติทั้งสองที่เกี่ยวข้องในการรวมเป็นคีย์ผสม
  • หากคุณดึงข้อมูลบันทึกโดยตรงโดยใช้ตัวระบุเฉพาะเช่นชื่อผู้ใช้หรืออีเมลนั่นควรเป็นดัชนีที่ไม่ซ้ำกัน
  • หากคุณดึงชุดของระเบียนจากhas_manyความสัมพันธ์โดยใช้ขอบเขตตรวจสอบให้แน่ใจว่ามีดัชนีที่มีhas_manyForeign Key และคอลัมน์ขอบเขตตามลำดับนั้น

เป้าหมายของดัชนีคือการกำจัดการดำเนินการ "สแกนตาราง" หรือ "เรียงไฟล์" ที่น่ากลัวซึ่งเกิดขึ้นเมื่อข้อมูลของคุณไม่ได้รับการจัดทำดัชนีอย่างถูกต้อง

พูดง่ายๆคือดูการสืบค้นที่สร้างขึ้นโดยแอปพลิเคชันของคุณและตรวจสอบให้แน่ใจว่าคอลัมน์ที่อ้างอิงในWHEREหรือHAVINGเงื่อนไขและส่วนORDER BYคำสั่งแสดงตามลำดับนั้น


1
ฉันสงสัยว่าทำไม Rails จึงไม่ได้หมายความถึงดัชนีหากคุณต้องการใช้มันสำหรับคีย์ต่างประเทศทุกครั้ง มีสถานการณ์ที่ไม่ควรจัดทำดัชนีหรือไม่?
ทริป

1
@trip มันค่อนข้างง่ายที่จะเพิ่มindex: trueคำจำกัดความคอลัมน์ของคุณสำหรับกรณีธรรมดา ๆ แต่บางครั้งคุณอาจต้องการควบคุมมันมากขึ้น การมีดัชนีโดยค่าเริ่มต้นในคีย์ต่างประเทศไม่ใช่ค่าเริ่มต้นที่น่ากลัว แต่อาจทำให้ผู้คนประหลาดใจได้
tadman

13
  • ทำดัชนีคีย์ต่างประเทศเสมอ
  • จัดทำดัชนีคอลัมน์ที่คุณจะเรียงลำดับตามเสมอ
  • เขตข้อมูลที่ไม่ซ้ำกันทั้งหมด (เพื่อให้แน่ใจว่าเป็นเอกลักษณ์ที่ระดับฐานข้อมูลการโยกย้ายตัวอย่าง:. add_index :users, :email, unique: true)
  • หากคุณเรียงลำดับตามสองสิ่งหรือค้นหาด้วยสองสิ่งตัวอย่างเช่น order by [a, b]หรือfind where( a and b )คุณต้องมีดัชนีคู่:

ตัวอย่างที่เป็นรูปธรรม:

ถ้าคุณมี:

default_scope :order => 'photos.created_at DESC, photos.version DESC'

คุณควรเพิ่ม:

add_index :photos, [:created_at, :version]

หมายเหตุ: ดัชนีใช้พื้นที่เพิ่มเติมบนดิสก์และทำให้การสร้างและอัปเดตแต่ละระเบียนช้าลงเนื่องจากต้องสร้างดัชนีใหม่แต่ละรายการ

เครดิต:

https://tomafro.net/2009/08/using-indexes-in-rails-choosing-additional-indexes , ราง - created_at เมื่อผู้ใช้สั่งซื้อคุณควรเพิ่ม Index ในตารางหรือไม่? และคำตอบข้างต้น

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.