1

クエリは次のとおりです。

SELECT COUNT(*) AS c, MAX(`followers_count`) AS max_fc, 
       MIN(`followers_count`) AS min_fc, MAX(`following_count`) AS max_fgc,
       MIN(`following_count`) AS min_fgc, SUM(`followers_count`) AS fc,
       SUM(`following_count`) AS fgc, MAX(`updates_count`) AS max_uc,
       MIN(`updates_count`) AS min_uc, SUM(`updates_count`) AS uc
FROM `profiles`
WHERE `twitter_id` IN (SELECT `followed_by` 
                       FROM `relations` 
                       WHERE `twitter_id` = 123);

profiles2つのテーブルはとですrelations。どちらも1,000,000行を超える、InnoDBエンジンを備えています。どちらもにインデックスがありtwitter_id、 ( 、 )relationsに追加のインデックスがあります。クエリの実行には6秒以上かかりますが、これは本当にイライラします。どういうわけかこれに参加できることは知っていますが、MySQLの知識はそれほどクールではないので、あなたの助けを求めています。twitter_idfollowed_by

よろしくお願いします=)

乾杯、K〜

更新しました

さて、私はなんとか2.5秒まで下がることができました。INNER JOINを使用して、3つのインデックスペアを追加しました。EXPLAINの結果は次のとおりです。

id, select_type, table, type, possible_keys, 
    key, key_len, ref, rows, Extra

1, 'SIMPLE', 'r', 'ref', 'relation', 
    'relation', '4', 'const', 252310, 'Using index'

1, 'SIMPLE', 'p', 'ref', 'PRIMARY,twiter_id,id_fc,id_fgc,id_uc', 
    'id_uc', '4', 'follerme.r.followed_by', 1, ''

お役に立てれば。

別の更新

両方のテーブルのSHOWCREATETABLEステートメントは次のとおりです。

CREATE TABLE `profiles` (
  `twitter_id` int(10) unsigned NOT NULL,
  `screen_name` varchar(45) NOT NULL default '',
  `followers_count` int(10) unsigned default NULL,
  `following_count` int(10) unsigned default NULL,
  `updates_count` int(10) unsigned default NULL,
  `location` varchar(45) default NULL,
  `bio` varchar(160) default NULL,
  `url` varchar(255) default NULL,
  `image` varchar(255) default NULL,
  `registered` int(10) unsigned default NULL,
  `timestamp` int(10) unsigned default NULL,
  `relations_timestamp` int(10) unsigned default NULL,
  PRIMARY KEY  USING BTREE (`twitter_id`,`screen_name`),
  KEY `twiter_id` (`twitter_id`),
  KEY `screen_name` USING BTREE (`screen_name`,`twitter_id`),
  KEY `id_fc` (`twitter_id`,`followers_count`),
  KEY `id_fgc` (`twitter_id`,`following_count`),
  KEY `id_uc` (`twitter_id`,`updates_count`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8

CREATE TABLE `relations` (
  `id` int(10) unsigned NOT NULL auto_increment,
  `twitter_id` int(10) unsigned NOT NULL default '0',
  `followed_by` int(10) unsigned default NULL,
  `timestamp` int(10) unsigned default NULL,
  PRIMARY KEY  USING BTREE (`id`,`twitter_id`),
  UNIQUE KEY `relation` (`twitter_id`,`followed_by`)
) ENGINE=InnoDB AUTO_INCREMENT=1209557 DEFAULT CHARSET=utf8

うわー、なんてめちゃくちゃ=)ごめんなさい!

4

5 に答える 5

3

結合は次のようになります。

SELECT COUNT(*) AS c,
MAX(p.`followers_count`) AS max_fc,
MIN(p.`followers_count`) AS min_fc,
MAX(p.`following_count`) AS max_fgc,
MIN(p.`following_count`) AS min_fgc,
SUM(p.`followers_count`) AS fc,
SUM(p.`following_count`) AS fgc,
MAX(p.`updates_count`) AS max_uc,
MIN(p.`updates_count`) AS min_uc,
SUM(p.`updates_count`) AS uc
FROM `profiles` AS p
INNER JOIN `relations` AS r ON p.`twitter_id` = r.`followed_by`
WHERE r.`twitter_id` = 123;

最適化するには、両方のクエリでEXPLAINSELECT...を実行する必要があります。

于 2009-07-09T14:33:55.747 に答える
1
SELECT COUNT(*) AS c,
  MAX(`followers_count`) AS max_fc, MIN(`followers_count`) AS min_fc,
  MAX(`following_count`) AS max_fgc, MIN(`following_count`) AS min_fgc,
  SUM(`followers_count`) AS fc, SUM(`following_count`) AS fgc,
  MAX(`updates_count`) AS max_uc, MIN(`updates_count`) AS min_uc, SUM(`updates_count`) AS uc
FROM `profiles`
JOIN `relations`
  ON (profiles.twitter_id = relations.followed_by)
WHERE relations.twitted_id = 123;

少し速いかもしれませんが、それが本当にそうかどうかを測定して確認する必要があります。

于 2009-07-09T14:35:33.780 に答える
1

次の複合インデックスを作成します。

profiles (twitter_id, followers_count)
profiles (twitter_id, following_count)
profiles (twitter_id, updates_count)

神のために、クエリプランを投稿します。

ちなみに、これは何行COUNT(*)戻りますか?

アップデート:

テーブルの行はかなり長いです。選択したすべてのフィールドに複合インデックスを作成します。

profiles (twitter_id, followers_count, following_count, updates_count)

JOINクエリがそのインデックスから必要なすべての値を取得できるようにします。

于 2009-07-09T14:35:57.053 に答える
1

count(*)はInnoDBエンジンでの非常にコストのかかる操作ですが、その部分なしでこのクエリを試しましたか?処理時間が最も長い場合は、毎回クエリを実行する代わりに、実行中の値を保持できます。

于 2009-07-09T14:36:29.627 に答える
1

私はプログラマーの観点からこの問題に取り組みます。元のクエリの各フィールドに関連付けられた最大値、最小値、合計値を格納し、テーブルレコードを更新および追加するたびにそれらの値を更新する、個別のテーブル(またはどこかにストレージ領域)があります。(ただし、正しく処理されない場合、削除は問題になる可能性があります)。

これらの値を入力するための元のクエリが完了した後(これは、投稿したクエリとほぼ同じです)、すべてを一度に計算するのではなく、基本的に最終的なクエリをデータテーブルから1つの行を取得するように減らします。

于 2009-07-09T15:02:02.150 に答える