投票システム (好き/嫌い) を備えた Web サイトを持っています。
アプリケーションは別の開発者によって開発されており、現在、Web サイトはますます大きくなっており、パフォーマンスが真剣に考慮されています。
私は次の表を持っています:
CREATE TABLE `vote` (
`id` int(11) NOT NULL auto_increment,
`article_id` int(11) NOT NULL,
`token` varchar(64) collate utf8_unicode_ci NOT NULL,
`type` int(1) NOT NULL,
PRIMARY KEY (`id`),
KEY `article_id` (`article_id`)
) ENGINE=InnoDB;
トークン列は、各ユーザー/投票/日付を識別するために使用されます。これは、ユーザーの指紋の一部である一意のトークンであり、一度投票して投票タイプを変更できるようにします。
最も遅いクエリの 1 つは次のとおりです。
SELECT count(*) AS `nb` FROM `vote` WHERE (token = '00123456789012345678901234567890');
サーバーがシャットダウンしていない場合、戻るのに 10 秒近くかかることがあります。
ここではキャッシュを使用できません。投票を許可するかどうかをリアルタイムで確認し、カウントをインクリメントする必要があるためです。
アプリケーションのあらゆる場所で使用されている依存関係に依存しすぎているため、多くのアプリケーション ロジックを変更することはできません (設計が不適切でした)。
そのため、パフォーマンスを少しでも改善するためのオプションを探しています。
編集:トークン列にインデックスがあります
〜2,000,000行あり、すべてのトークンはほぼ一意です
編集:
私はあなたのすべてのアドバイスでベンチマークを実行しました:
Top average queries
1. SELECT COUNT(*) AS nb FROM `vote` WHERE (`token` = '%s') completed in 2.19790604115 sec
2. SELECT COUNT(`id`) AS nb FROM `vote` WHERE (`token` = '%s') completed in 2.28792096376 sec
3. SELECT COUNT(`id`) AS nb FROM `vote` WHERE (`token` = '%s') GROUP BY `token` completed in 2.3732401371 sec
4. SELECT COUNT(*) AS nb FROM `vote` WHERE (`token` = '%s') GROUP BY `token` completed in 2.57634830475 sec
3 番目のクエリが最も速い場合もありますが、最悪の場合もあります。
各クエリが20回実行される場所で10回実行しました
このベンチマークを INDEXES なしで実行しました (上の 1 つを除くid
) 。
それは奇妙です、私は COUNT(id) がクエリを少し高速化したと思います。