1

私は2つのテーブルを持っています:

1位:

    CREATE TABLE IF NOT EXISTS `tags` (
  `i` int(10) NOT NULL AUTO_INCREMENT,
  `id` int(10) NOT NULL,
  `k` varchar(32) COLLATE utf8_bin NOT NULL,
  主キー (`i`)、
  キー `k` (`k`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_bin AUTO_INCREMENT=1505426 ;

そして2番目:

存在しない場合はテーブルを作成 `w` (
  `id` int(7) NOT NULL,
  `title` varchar(255) COLLATE utf8_bin NOT NULL,
  `k1` varchar(24) COLLATE utf8_bin NOT NULL,
  `k2` varchar(24) COLLATE utf8_bin NOT NULL,
  `k3` varchar(24) COLLATE utf8_bin NOT NULL,
  `k4` varchar(24) COLLATE utf8_bin NOT NULL,
  `k5` varchar(24) COLLATE utf8_bin NOT NULL,
  `k6` varchar(24) COLLATE utf8_bin NOT NULL,
  `k7` varchar(24) COLLATE utf8_bin NOT NULL,
  `k8` varchar(24) COLLATE utf8_bin NOT NULL,
  `w` int(5) NOT NULL,
  `h` int(5) NOT NULL,
  `s` varchar(32) COLLATE utf8_bin NOT NULL,
  `r` varchar(11) COLLATE utf8_bin NOT NULL,
  `v` int(7) NOT NULL,
  `c` varchar(32) COLLATE utf8_bin NOT NULL,
  `c1` varchar(6) COLLATE utf8_bin NOT NULL,
  `c2` varchar(6) COLLATE utf8_bin NOT NULL,
  `c3` varchar(6) COLLATE utf8_bin NOT NULL,
  `c4` varchar(6) COLLATE utf8_bin NOT NULL,
  `c5` varchar(6) COLLATE utf8_bin NOT NULL,
  `c6` varchar(6) COLLATE utf8_bin NOT NULL,
  `m` varchar(4) COLLATE utf8_bin NOT NULL,
  `t` int(10) NOT NULL,
  `i` int(6) NOT NULL,
  `o` int(6) NOT NULL,
  `f` varchar(255) COLLATE utf8_bin NOT NULL,
  主キー (`id`)、
  KEY `キーワード` (`k1`,`k2`,`k3`,`k4`,`k5`,`k6`,`k7`,`k8`),
  KEY `カテゴリ` (`c`),
  KEY `color1` (`c1`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin ROW_FORMAT=DYNAMIC;

テーブル 'tags' から 2 つの単語 ($search1 + $search2) を検索し、'w' テーブルで ID を見つけようとしています。クエリ:

SELECT w.id,w.title,w.k1,w.k2,w.k3,w.k4,w.k5,w.k6,w.k7,ww,wh,ws,w.c1,w.c2 ,w.c3,w.c4,w.c5,w.c6,wm,wf
FROM タグ、タグとしてのタグ2、w
WHERE tags.k ='$search1' AND tags2.k = '$search2'
および tags.id = tags2.id および tags2.id = w.id
ORDER BY `w`.`id`desc 制限 24

問題は、EXPLAIN 関数が「Using where; Using temporary; Using filesort」と表示されることです。また、この my type 検索システムを最適化する別の方法があると思います。実際にはすべてのデータが「w」テーブルにありますが、正確に検索する方法がわかりません。どんな助けにも感謝します。

編集:これについてのもう少しの情報

テーブル「タグ」1505425 レコード InnoDB = 65,9 MiB

テーブル 'w' 398900 レコード、InnoDB = 140,3 MiB

この(更新された)クエリの後:

select `w`.`id` AS `id`,`w`.`title` AS `title`,`w`.`k1` AS `k1`,`w`.`k2` AS `k2`,` w`.`k3` AS `k3`,`w`.`k4` AS `k4`,`w`.`k5` AS `k5`,`w`.`k6` AS `k6`,`w` .`k7` AS `k7`,`w`.`k8` AS `k8`,`w`.`w` AS `w`,`w`.`h` AS `h`,`w`.` s` AS `s`,`w`.`c1` AS `c1`,`w`.`c2` AS `c2`,`w`.`c3` AS `c3`,`w`.`c4` AS `c4`,`w`.`c5` AS `c5`,`w`.`c6` AS `c6`,`w`.`m` AS `m`,`w`.`f` AS ` f` from `tags` join `tags` `tags2` join `w` where ((`tags`.`k` = '$search1') and (`tags2`.`id` = `tags`.`id` ) および (`w`.`id` = `tags`.`id`) および (`tags2`.`k` = '$search2')) `tags`.`i` desc limit 0,24 による順序。

mysql はまだ表示されます:

+----+-------------+------------+--------+-------- -------+---------+---------+-------------+------+- ------+---------------------------------+
| | ID | select_type | テーブル | タイプ | 可能な_キー | キー | key_len | 参照 | 行 | 行 フィルタリングされた | エクストラ |
+----+-------------+------------+--------+-------- -------+---------+---------+-------------+------+- ------+---------------------------------+
| | 1 | シンプル | タグ | 参照 | k,id | k | 98 | 定数 | 902 | 100.00 | where を使用します。ファイルソートの使用 |
| | 1 | シンプル | タグ2 | 参照 | k,id | ID | 4 | db.tags.id | 4 | 100.00 | where | の使用
| | 1 | シンプル | w | eq_ref | プライマリ | プライマリ | 4 | db.tags2.id | 1 | 100.00 | where | の使用
+----+-------------+------------+--------+-------- -------+---------+---------+-------------+------+- ------+---------------------------------+
3 行セット、1 警告 (0.00 秒)

1 つの警告ですが、それでもすべてが同じままです。パフォーマンスを向上させるための解決策はありますか? 現時点では問題なく動作しますが、後ですべてが遅くなると思います。

4

2 に答える 2

1

ストレージ エンジンを混在させています。mySQL は、ストレージ エンジン間でテーブルを結合するのに苦労しています。

前:

mysql> explain SELECT w.id,w.title,w.k1,w.k2,w.k3,w.k4,w.k5,w.k6,w.k7,w.w,w.h,w.s,w.c1,w.c2,w.c3,w.c4,w.c5,w.c6,w.m,w.f FROM tags,tags as tags2,w WHERE tags.k ='$search1' AND tags2.k = 'search2' and tags.id = tags2.id and tags2.id = w.id ORDER BY `w`.`id`desc limit 24;
+----+-------------+-------+--------+---------------+---------+---------+-------------+------+----------------------------------------------+
| id | select_type | table | type   | possible_keys | key     | key_len | ref         | rows | Extra                                        |
+----+-------------+-------+--------+---------------+---------+---------+-------------+------+----------------------------------------------+
|  1 | SIMPLE      | tags  | ref    | k             | k       | 98      | const       |    1 | Using where; Using temporary; Using filesort |
|  1 | SIMPLE      | tags2 | ref    | k             | k       | 98      | const       |    1 | Using where                                  |
|  1 | SIMPLE      | w     | eq_ref | PRIMARY       | PRIMARY | 4       | tmp.tags.id |    1 |                                              |
+----+-------------+-------+--------+---------------+---------+---------+-------------+------+----------------------------------------------+

w を MyISAM に変更します。

mysql> alter table w engine MyISAM;
Query OK, 1 row affected (0.01 sec)
Records: 1  Duplicates: 0  Warnings: 0

後:

mysql> explain SELECT w.id,w.title,w.k1,w.k2,w.k3,w.k4,w.k5,w.k6,w.k7,w.w,w.h,w.s,w.c1,w.c2,w.c3,w.c4,w.c5,w.c6,w.m,w.f FROM tags,tags as tags2,w WHERE tags.k ='$search1' AND tags2.k = 'search2' and tags.id = tags2.id and tags2.id = w.id ORDER BY `w`.`id`desc limit 24;
+----+-------------+-------+--------+---------------+------+---------+-------+------+-------------+
| id | select_type | table | type   | possible_keys | key  | key_len | ref   | rows | Extra       |
+----+-------------+-------+--------+---------------+------+---------+-------+------+-------------+
|  1 | SIMPLE      | w     | system | PRIMARY       | NULL | NULL    | NULL  |    1 |             |
|  1 | SIMPLE      | tags  | ref    | k             | k    | 98      | const |    1 | Using where |
|  1 | SIMPLE      | tags2 | ref    | k             | k    | 98      | const |    1 | Using where |
+----+-------------+-------+--------+---------------+------+---------+-------+------+-------------+
3 rows in set (0.00 sec)
于 2012-11-04T18:05:04.477 に答える
0

Vagiz、更新されたクエリは問題ないようです。

select `w`.`id` AS `id`,`w`.`title` AS `title`,`w`.`k1` AS `k1`,`w`.`k2` AS `k2`,
`w`.`k3` AS `k3`,`w`.`k4` AS `k4`,`w`.`k5` AS `k5`,`w`.`k6` AS `k6`,`w`.
`k7` AS `k7`,`w`.`k8` AS `k8`,`w`.`w` AS `w`,`w`.`h` AS `h`,`w`.`s` AS `s`,
`w`.`c1` AS `c1`,`w`.`c2` AS `c2`,`w`.`c3` AS `c3`,`w`.`c4` AS `c4`,
`w`.`c5` AS `c5`,`w`.`c6` AS `c6`,`w`.`m` AS `m`,`w`.`f` AS `f`
from `tags` join `tags` `tags2` join `w` where ((`tags`.`k` = '$search1') 
and (`tags2`.`id` = `tags`.`id`) and (`w`.`id` = `tags`.`id`) 
and (`tags2`.`k` = '$search2')) order by `tags`.`i` desc limit 0,24;

次の説明結果が生成される場合:

+----+-------------+------------+--------+---------------+---------+---------+-------------+------+----------+-----------------------------+
| id | select_type | table      | type   | possible_keys | key     | key_len | ref         | rows | filtered | Extra                       |
+----+-------------+------------+--------+---------------+---------+---------+-------------+------+----------+-----------------------------+
|  1 | SIMPLE      | tags       | ref    | k,id          | k       | 98      | const       |  902 |   100.00 | Using where; Using filesort |
|  1 | SIMPLE      | tags2      | ref    | k,id          | id      | 4       | db.tags.id  |    4 |   100.00 | Using where                 |
|  1 | SIMPLE      | w          | eq_ref | PRIMARY       | PRIMARY | 4       | db.tags2.id |    1 |   100.00 | Using where                 |
+----+-------------+------------+--------+---------------+---------+---------+-------------+------+----------+-----------------------------+
3 rows in set, 1 warning (0.00 sec)

ファイルソートとパフォーマンスについて心配する必要はありません。Mysqlパフォーマンスブログから:

真実は、filesortの名前が間違っているということです。インデックスからソートを実行できない場合は常に、ファイルソートです。それはファイルとは何の関係もありません。Filesortは「sort」と呼ばれるべきです。本質的にクイックソートです。

于 2012-11-04T23:14:00.437 に答える