Kiedy dodać jakie indeksy do tabeli w Rails

Mam pytanie dotyczące bazy danych Rails.

  • Czy powinienem dodać "index" do wszystkich kluczy obcych, takich jak"xxx_id"?
  • Czy powinienem dodać "index" Do automatycznie tworzonej kolumny "id"?
  • Czy powinienem dodać " index (unique) "do automatycznie utworzonej kolumny" id"?

  • Jeśli dodam indeks do dwóch kluczy obcych na raz (add_index (:users, [:category, :state_id]), co się stanie? Czym to się różni od dodawania indeksu dla każdego klucza?

    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
    

Świetna odpowiedź więc daleko. Dodatkowe pytanie.

  • powinienem dodać "index with unique" dla xxx_id, prawda?
Author: TK., 2010-09-07

3 answers

Czy powinienem dodać "index" do wszystkich kluczy obcych, takich jak"xxx_id"?

Byłoby lepiej, ponieważ przyspiesza wyszukiwanie w sortowaniu w tej kolumnie. A klucze obce to coś, czego często szukamy.

Od wersji 5 rails indeks zostanie utworzony automatycznie, aby uzyskać więcej informacji zobacz tutaj .

Czy powinienem dodać "index" Do automatycznie tworzonej kolumny "id"?

Nie, to jest już zrobione przez rails

Czy powinienem dodać " index (unique) "do automatycznie tworzonej kolumny" id"?

Nie, to samo co wyżej

Jeśli dodam indeks do dwóch kluczy obcych na raz (add_index (:users, [:category_id, :state_id]), co się stanie? Czym to się różni od dodawania indeksu dla każdego klucza?

Wtedy indeks jest połączonym indeksem dwóch kolumn. To nie ma sensu, chyba, że chcesz wszystkie wpisy dla jednego category_id i jeden state_id (powinien być category_id a nie category) w tym samym czas.

Indeks taki jak ten przyspieszyłby następujące żądanie:

# 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)

Gdzie

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

Przyspieszy te żądania:

# 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)

Powinienem dodać "index with unique" dla xxx_id, prawda?

Nie, ponieważ jeśli to zrobisz, tylko jeden użytkownik może być w jednej kategorii, ale znaczenie kategorii jest takie, że możesz umieścić więcej wielu użytkowników w jednej kategorii. W swoim User modelu masz coś takiego belongs_to :category a w swojej kategorii model coś w stylu has_many :users. Jeśli masz relację has_many, pole foreign_key nie może być unikalne!

Aby uzyskać bardziej szczegółowe informacje na ten temat należy spojrzeć na tadman ' s great odpowiedź.

 176
Author: jigfox,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-07-10 12:50:44

Indeksowanie może być trudną, subtelną rzeczą, ale istnieją ogólne zasady, które mają zastosowanie, które mogą znacznie ułatwić określenie, którego użyć.

Pierwszą rzeczą do zapamiętania jest to, że indeksy mogą działać w więcej niż jeden sposób. Indeks Na A, B, C działa również dla A, B i po prostu a, więc możesz zaprojektować swoje indeksy, aby były bardziej uniwersalne, jeśli zamówisz je poprawnie. Książka telefoniczna jest indeksowana na nazwisko, imię, dzięki czemu można łatwo wyszukać osoby po ich nazwisku lub kombinacji nazwiska i imię. Nie można jednak odszukać ich bezpośrednio po ich imieniu. Potrzebowałbyś do tego osobnego indeksu. To samo dotyczy numeru telefonu, który również trzeba by zindeksować.

Mając to na uwadze, jest wiele rzeczy, które będą dyktować sposób tworzenia indeksów:

  • Jeśli masz belongs_to-has_many parowanie relacji, musisz mieć indeks na obcym kluczu używanym.
  • jeśli zamówisz swoje rekordy, A jest ich duża liczba, która będzie paginowana, kolumnę order należy dodać na końcu indeksu.
  • jeśli masz relację has_many :through, twoja tabela join powinna mieć unikalny indeks dla obu właściwości zaangażowanych w join jako klucz złożony.
  • jeśli pobierasz rekord bezpośrednio przy użyciu unikalnego identyfikatora, takiego jak nazwa użytkownika lub adres e-mail, powinien to być unikalny indeks.
  • jeśli pobierasz zbiory rekordów z relacji has_many za pomocą zakresu, upewnij się, że istnieje indeks zawierający has_many klucz obcy i kolumnę zakresu w tej kolejności.

Celem z indeksami jest wyeliminowanie przerażających operacji "skanowania tabeli" lub "sortowania plików", które występują, gdy dane nie są odpowiednio indeksowane.

W prostych słowach, spójrz na zapytania generowane przez Twoją aplikację i upewnij się, że kolumny wymienione w WHERE lub HAVING warunki i ORDER BY klauzule są reprezentowane w tej kolejności.

 113
Author: tadman,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-09-07 17:30:13
  • zawsze indeksuj klucze obce
  • zawsze indeksuj kolumny według
  • wszystkie unikalne pola (aby zapewnić unikalność na poziomie bazy danych. Przykładowa migracja: add_index :users, :email, unique: true)
  • jeśli zamawiasz według dwóch rzeczy, lub wyszukujesz według dwóch rzeczy, na przykład: order by [a, b] lub find where( a and b ), wtedy potrzebny jest podwójny indeks:

Konkretny przykład:

Jeśli masz:

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

Powinieneś dodać:

add_index :photos, [:created_at, :version]

Uwaga: Indeks zajmuje dodatkowe miejsce na dysku i czyni go wolniejszym do Utwórz i zaktualizuj każdy rekord, ponieważ musi odbudować każdy indeks.

Kredyt:

Https://tomafro.net/2009/08/using-indexes-in-rails-choosing-additional-indexes, rails-created_at przy zamawianiu należy dodać Indeks do tabeli?, oraz odpowiedzi powyżej.

 14
Author: Will Taylor,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 11:54:33