ページの読み込み時にこのクエリを初めて実行するときは、約1ミリ秒かかるはずですが、常に約100ミリ秒かかります。MySQLコンソールとPhpMyAdminを介してまったく同じクエリを実行しましたが、常に高速です。
私は次のようにPHP内で時間を計りました:
$t = microtime(true);
mysql_query($sql, $this->id);
die((microtime(true)-$t)*1000);
まったく同じクエリを2回実行すると(たとえば、中央の行を複製して)、2回目はほぼ瞬時に実行されます。
クエリは次のようになります。
SELECT `user_id`, `login`, `first_name`, `last_name`, `name`, `email`, ... FROM `users` WHERE `user_id`='1000' LIMIT 1
実験の結果、選択するフィールドの数を減らすと、突然高速に実行されることがわかりました。26番目の列を追加すると、1ミリ秒から100ミリ秒にジャンプします。26列目は何でも構いませんが、「1」のような定数でも急に遅くなります。
これを引き起こしている可能性があり、どうすれば修正できますか?
スキーマ:
CREATE TABLE `user` (
`f1` int(11) unsigned NOT NULL DEFAULT '0',
`f2` varchar(50) NOT NULL DEFAULT '',
`f3` varchar(32) NOT NULL DEFAULT '',
`f4` varchar(50) DEFAULT NULL,
`f5` varchar(50) DEFAULT NULL,
`f6` varchar(100) NOT NULL DEFAULT 'Anonymous',
`f7` varchar(100) DEFAULT NULL,
`f8` varchar(100) NOT NULL DEFAULT 'Anonymous',
`f9` tinyint(1) NOT NULL DEFAULT '0',
`f10` tinyint(1) unsigned NOT NULL DEFAULT '0',
`f11` varchar(250) DEFAULT NULL,
`f12` int(10) unsigned NOT NULL DEFAULT '0',
`f13` varchar(250) NOT NULL DEFAULT '',
`f14` int(10) unsigned NOT NULL DEFAULT '0',
`f15` varchar(100) DEFAULT NULL,
`f16` varchar(25) DEFAULT NULL,
`f17` varchar(25) DEFAULT NULL,
`f18` varchar(25) DEFAULT NULL,
`f19` varchar(200) DEFAULT NULL,
`f20` varchar(50) DEFAULT NULL,
`f21` varchar(50) DEFAULT 'BC',
`f22` varchar(50) DEFAULT 'Canada',
`f23` varchar(20) DEFAULT NULL,
`f24` bigint(20) unsigned NOT NULL DEFAULT '0',
`f25` bigint(20) unsigned NOT NULL DEFAULT '0',
`f26` int(5) unsigned zerofill NOT NULL DEFAULT '00000',
`f27` tinyint(1) NOT NULL DEFAULT '0',
`f28` tinyint(1) unsigned NOT NULL DEFAULT '0',
`f29` tinyint(1) NOT NULL DEFAULT '0',
`f30` tinyint(1) unsigned NOT NULL DEFAULT '0',
`f31` varchar(50) DEFAULT NULL,
`f32` varchar(100) NOT NULL DEFAULT '',
`f33` bigint(20) unsigned NOT NULL DEFAULT '0',
`f34` bigint(20) unsigned NOT NULL DEFAULT '0',
`f35` varchar(250) DEFAULT NULL,
`f36` text NOT NULL,
`f37` tinyint(1) unsigned NOT NULL DEFAULT '0',
`f38` bigint(20) NOT NULL DEFAULT '0',
`f39` bigint(20) NOT NULL DEFAULT '0',
`f40` tinyint(1) unsigned NOT NULL DEFAULT '0',
`f41` tinyint(1) unsigned NOT NULL DEFAULT '0',
PRIMARY KEY (`f1`),
UNIQUE KEY `f2` (`f2`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
罪のない人を保護するためにフィールド名を変更しました。
更新:魔法の列の制限について間違っていた可能性があります。結局のところ、これはバイト制限だと思います...実際に必要な少数のフィールドを除いて、すべての数値で試しました。
SELECT `f1`, `f2`, `f3`, `f4`, `f5`, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55 FROM `wx_user` WHERE `user_id`='1000' LIMIT 1
それは1msで実行されます。最後に「56」を追加すると、約100msかかります。
私はさらにいくつかのテストを行いました:
mysql_query("SELECT 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' FROM `user` WHERE `f1`='1000' LIMIT 1");
1200〜1300 aのどこかで、1msから100msにジャンプします。
より多くの列を使用して同じことを繰り返すことができますが、データ(int)は小さくなります。
これは私に2つのことを示唆しています:
- 送信されるバイト数と関係があります
- 約50intを選択すると、単一の1300 charフィールドを選択するのと同じ効果があるため、列を追加するオーバーヘッドは非常に大きくなります。
今考えてみると、この数はジョンが提案した数に非常に近いものです。1300文字+オーバーヘッドは、ジョンが言及した1500MTUの制限におそらく等しいでしょう。
それはMySQL設定ですか、それともOS設定ですか?私が実験できることはありますか?