1

私は 500 万行のデータベースを持っていますが、データベースが大きくなり、それを操作するのがますます難しくなっています。

テーブルを 10 個のテーブル (v0_table、v1_table... v9_table) に分割することをお勧めします。番号 (v*) はユーザー ID の最初の番号です。

私の場合、ユーザーのIDは自動インクリメントではないため、これらの10個のテーブルでデータが均等にソートされます。

問題は、私が似たようなことをしたことがないということです....

誰でも欠点を見つけることができますか?

編集:

構造またはクエリの調整についてご協力いただければ幸いです。したがって、最も遅いクエリは次のクエリです。

SELECT logos.user, 
       logos.date, 
       logos.level, 
       logos.title, 
       Count(guesses.id), 
       Sum(guesses.points) 
FROM   logos 
       LEFT JOIN guesses 
              ON guesses.user = '".$user['uid']."' 
                 AND guesses.done = '1' 
                 AND guesses.logo = logos.id 
WHERE  open = '1' 
GROUP  BY level 

どこでテーブルを推測するか:

+--------+------------+------+-----+-------------------+----------------+
| Field  | Type       | Null | Key | Default           | Extra          |
+--------+------------+------+-----+-------------------+----------------+
| id     | int(11)    | NO   | PRI | NULL              | auto_increment |
| logo   | int(11)    | NO   | MUL | NULL              |                |
| user   | int(11)    | NO   | MUL | NULL              |                |
| date   | timestamp  | NO   |     | CURRENT_TIMESTAMP |                |
| points | int(4)     | YES  | MUL | 100               |                |
| done   | tinyint(1) | NO   | MUL | 0                 |                |
+--------+------------+------+-----+-------------------+----------------+

ロゴステーブル:

+-------+--------------+------+-----+-------------------+----------------+
| Field | Type         | Null | Key | Default           | Extra          |
+-------+--------------+------+-----+-------------------+----------------+
| id    | int(11)      | NO   | PRI | NULL              | auto_increment |
| name  | varchar(100) | NO   |     | NULL              |                |
| img   | varchar(222) | NO   | MUL | NULL              |                |
| level | int(3)       | NO   | MUL | NULL              |                |
| date  | timestamp    | NO   | MUL | CURRENT_TIMESTAMP |                |
| user  | int(11)      | NO   | MUL | NULL              |                |
| open  | tinyint(1)   | NO   | MUL | 0                 |                |
+-------+--------------+------+-----+-------------------+----------------+

説明:

+----+-------------+---------+------+----------------+------+---------+-------+------+----------------------------------------------+
| id | select_type | table   | type | possible_keys  | key  | key_len | ref   | rows | Extra                                        |
+----+-------------+---------+------+----------------+------+---------+-------+------+----------------------------------------------+
|  1 | SIMPLE      | logos   | ref  | open           | open | 1       | const |  521 | Using where; Using temporary; Using filesort |
|  1 | SIMPLE      | guesses | ref  | done,user,logo | user | 4       | const |   87 |                                              |
+----+-------------+---------+------+----------------+------+---------+-------+------+----------------------------------------------+
4

3 に答える 3

0

問題は、データが多すぎることではなく、このデータが適切にインデックス化されていないことです。インデックスを追加してみてください:

CREATE INDEX open_level ON logos(open, level)

これにより、 Using temporary;が排除されるはずです。ロゴでのファイルソートの使用

基本的に、このクエリではopen - forWHERE open = '1'level - forの2 つのことをカバーするために、このテーブルにインデックスが必要ですGROUP BY level。MySQL は最初にopenでフィルタリングし、次にレベルで結果をグループ化します(処理中に暗黙的に並べ替えます)。 )。

于 2012-06-19T11:19:10.847 に答える
0

短くて甘い:いいえ。これは決して良い考えではありません。テーブルは適切にインデックス化されていますか? MySQL は適切に調整されていますか? クエリは効率的ですか? キャッシュを使用していますか?

于 2012-06-19T01:01:06.837 に答える
0

テーブルを分割する代わりに、データベース内の他のテーブルを調べて、他のデータベースに分割できるかどうかを確認することができます。たとえば、決して結合されないテーブルは、このタイプの垂直分割の優れた候補です。

これにより、より小さいデータ セット用にハードウェアを最適化できます。

于 2012-06-19T01:05:00.643 に答える