Apakah membagi tabel 'pengguna' untuk tujuan otentikasi adalah ide yang bagus?

8

Misalkan saya memiliki tabel pengguna di situs saya di mana ada sekitar 2-3 Juta pengguna (catatan) di dalam tabel.

Untuk mempercepat proses login saya, apakah ini pendekatan yang baik untuk membagi tabel pengguna saya, satu untuk informasi mereka dan satu lagi untuk login mereka.

Jika kami dapat menjalankan kueri yang mirip dengan yang di bawah ini dari satu tabel:

select username,password from users where username=`test` AND password=****

Apakah perlu membaginya, dan apakah ini mempercepat proses login situs saya?

ALH
sumber
1
Menambahkan ini hanya sebagai komentar karena itu bukan jawaban langsung untuk pertanyaan Anda. Mungkin ini yang Anda lakukan di luar kueri sampel, tetapi praktik yang sangat buruk untuk menyimpan kata sandi yang sebenarnya di basis data Anda. Anda ingin menyimpannya sebagai has dan kemudian query seperti di mana password_hash = hash ($ userEnteredPassword)
atxdba
@ atxdba sebenarnya saya hash mereka, tapi di sini saya hanya memberi contoh.
ALH

Jawaban:

10

IMHO Anda tidak perlu membaginya secara fisik. Namun, akan lebih baik untuk menyimpannya.

Jika userstabel menggunakan Mesin Penyimpanan MyISAM, Anda memiliki keuntungan yang bagus.

Karena MyISAM hanya menyimpan indeks, Anda dapat melakukan dua hal

  • Anda bisa membuat cache kunci khusus hanya untuk memuat indeks MyISAM untuk userstabel saja
  • Anda bisa mengindeks nama pengguna dan kata sandi untuk memaksa kueri untuk menekan cache kunci khusus itu saja

Pastikan indeks berikut ada untuk users

ALTER TABLE users ADD UNIQUE INDEX username_ndx (username);
ALTER TABLE users ADD UNIQUE INDEX username_password_ndx (username,password);

Ada dua (2) alasan utama untuk kedua indeks

ALASAN untuk indeks # 1

Indeks username_ndxmencegah nama pengguna memiliki banyak kata sandi, serta mencegah banyak pengguna dengan nama yang sama

ALASAN untuk indeks # 2

Indeks username_password_ndxmenyediakan indeks penutup . Dengan demikian, kueri Anda akan mencari nama pengguna dan kata sandi di cache MyISAM khusus, alih-alih memeriksa tabel.

Lebih Banyak Tautan tentang Prinsip-prinsip Indeks Penutupan

Hal berikutnya adalah benar-benar membuat cache kunci khusus itu. Berikut adalah perintah untuk membuat cache kunci 8MB dan memuat cache kunci khusus itu (Contoh: Jika tabelnya adalah mydb.users):

SET GLOBAL authentication_cache.key_buffer_size = 1024 * 1024 * 8;
CACHE INDEX mydb.users IN authentication_cache;
LOAD INDEX INTO CACHE mydb.users;

Anda harus meletakkan ketiga baris ini di file /var/lib/mysql/startup.sql

Tambahkan ini ke /etc/my.cnf

[mysqld]
init-file=/var/lib/mysql/startup.sql

Ini akan memuat cache setiap kali mysql dimulai

Cobalah !!!

UPDATE 2011-12-30 17:25 EDT

Jika Anda ingin mendapatkan ukuran yang tepat untuk mengatur cache, gunakan kueri berikut:

SELECT CONCAT('1024 * 1024 * ',ROUND(index_length/power(1024,2))) RecommendedCacheSize
FROM information_schema.tables WHERE table_name='users';

UPDATE 2011-12-30 23:21 EDT

Berikut adalah metode berdasarkan InnoDB

Anda masih membutuhkan indeks

ALTER TABLE users ADD UNIQUE INDEX username_ndx (username);
ALTER TABLE users ADD UNIQUE INDEX username_password_ndx (username,password);

Anda harus memastikan Pool Buffer InnoDB memiliki nama pengguna dan kata sandi yang tersedia. Anda mungkin harus melakukan pemindaian indeks lengkap saat startup mysql:

Langkah 1) Buat ReadUserPass.sql

echo "select username,password from users;" > /var/lib/mysql/ReadUserPass.sql

Langkah 2) Tambahkan skrip itu ke /etc/my.cnf

[mysqld]
init-file=/var/lib/mysql/ReadUserPass.sql

Langkah 3) Lakukan salah satu dari yang berikut ini

  • $ service mysql restart
  • mysql> source /var/lib/mysql/ReadUserPass.sql

Karena kedua kolom ini (nama pengguna dan kata sandi) berada di username_password_ndx, semua halaman indeks yang menyusun indeks ini dimuat ulang ke dalam Pool Buffer InnoDB. Ini diperlukan karena ada kemungkinan halaman indeks sedang dihapus. Untuk meminimalkan hal itu, tambah Ukuran Buffer Pool dan mulai ulang mysql (satu kali).

RolandoMySQLDBA
sumber
Sebenarnya saya menggunakan mesin penyimpanan InnoDB, tapi saya pikir proses cache akan baik-baik saja dengan itu, bukankah @RandooMySQLDBA?
ALH
Tidak. Langkah-langkah dalam jawaban saya hanya MyISAM.
RolandoMySQLDBA
Jika userstabel terlibat dalam transaksi, maka saya perlu mengirimkan jawaban lain hanya berdasarkan InnoDB.
RolandoMySQLDBA
Maaf saya tidak menyebutkan itu, saya tidak tahu mereka akan memiliki pendekatan yang berbeda!
ALH
Saya menjawab berdasarkan MyISAM karena saya ingin tabel pengguna di-cache di buffer kunci sendiri.
RolandoMySQLDBA
5

Sebuah tabel yang terdiri dari beberapa juta baris tidak perlu dipisah. Penyesuaian kinerja harus dilakukan melalui indeks. MySpace memiliki ratusan juta akun yang terdaftar dalam satu tabel dan kinerja di atas meja itu baik-baik saja. (Saya adalah seorang DBA untuk MySpace pada puncak penggunaannya.) Tabel dalam kasus itu mungkin 80-90 byte lebar (mungkin sedikit lebih).

mrdenny
sumber
Eh, seperti apa ukuran RAM itu?
Chibueze Opata
3

Apakah Anda benar-benar memiliki 2 juta pengguna? Kecuali Anda sudah memiliki masalah ini atau yakin bahwa Anda akan melakukannya, Anda mengoptimalkan cara sebelumnya. Tambahkan indeks gabungan pada bidang login dan kata sandi dan selesai dengan itu. Jangan mengoptimalkan kecuali Anda tahu Anda benar-benar memiliki masalah untuk dipecahkan. Saya yakin Anda memiliki masalah yang lebih besar untuk dipecahkan.

Aaron Brown
sumber
1
Apa yang Anda maksud dengan "Anda yakin saya memiliki masalah yang lebih besar untuk dipecahkan"?
ALH
1
Tidak masuk akal untuk menyelesaikan masalah ketika kita tahu dalam waktu dekat kita akan menghadapi banyak masalah. Pemecahan masalah ini adalah sakit kepala ketika ada banyak data di tabel! -1 untukmu.
ALH
2
Maksud saya ada dua ... jangan optimalkan sebelum Anda harus & 2 juta catatan tidak banyak. Indeks akan banyak.
Aaron Brown
2

Jika Anda menggunakan Mysql 5.1 dan lebih tinggi, Anda dapat mencoba mempartisi tabel Anda.
Pada pertanyaan Anda apakah mempercepat proses login, itu tergantung pada bagaimana sisa prosedur login (misalnya, jika permintaan Anda sekarang membutuhkan 0,05 detik, dan sisa kode membutuhkan 20 detik, saya lebih suka mengulang pikirkan seluruh rutinitas ...).
Juga, terlepas dari menggunakan partisi, jangan lupa untuk menambahkan indeks seperti yang ditunjukkan RolandoMySQLDBA .

a1ex07
sumber
Panggilan yang baik untuk menentukan penyebab sebenarnya dari masalah kinerja sebelum mengoptimalkan. Seringkali tidak seperti yang kita pikirkan. Penyetelan berbasis bukti adalah cara terbaik!
Stuart Woodward