非常に単純なクエリがあります。
SELECT * FROM sometable t WHERE somecol = 'somevalue' ORDER BY createdon DESC LIMIT 0,20000;
クラスター化されていない開発マシンでこのクエリを実行すると、0.07秒で実行されます。
クラスター化された負荷分散サーバーの1つで同じクエリを実行すると、完了するまでに30分以上かかります。両方のサーバーのデータはまったく同じです。
なぜこれが起こっているのですか?
セットアップに関する詳細は次のとおりです。
LIMIT
の近くにはありません。テーブルスキーマは次のとおりです。ここで、{X}はローカルマシンのInnoDBまたは本番サーバーのNDBClusterです。
CREATE TABLE `sometable` (
`Id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`UserId` bigint(20) unsigned NOT NULL,
`Cookie` varchar(255) DEFAULT NULL,
`somecol` varchar(30) DEFAULT NULL,
`IpAddress` varchar(255) DEFAULT NULL,
`SomeCollection` text,
`someothercolumn` decimal(6,2) NOT NULL,
`someothercolumn2` decimal(6,2) DEFAULT NULL,
`Result` tinyint(4) NOT NULL,
`Version` tinyint(4) NOT NULL,
`Source` varchar(255) DEFAULT NULL,
`CreatedOn` datetime NOT NULL,
PRIMARY KEY (`Id`),
KEY `CreatedOnIndex` (`CreatedOn`),
KEY `SomeColIndex` (`somecol`),
KEY `ResultIndex` (`Result`),
KEY `SomeCol2Index` (`someothercolumn2`)
) ENGINE={X} AUTO_INCREMENT=97043 DEFAULT CHARSET=latin1;
クエリは11,154レコードを返します。これは、クエリの正しい量です。
データノード間の遅延に関して、これは典型的なping要求が返すものです。
64 bytes from 192.168.3.45: icmp_req=1 ttl=64 time=0.479 ms
MySQL Clusterが本当に必要かどうかを検討することをお勧めします。これは、目的にとってはやり過ぎであり、複雑さを正当化できない可能性があります。レプリケーションを備えたMySQLマスターマスターまたはマスタースレーブインスタンスのペアは、多くのショップにとって十分であり、このシナリオでより優れたパフォーマンスを提供します。
現在のアーキテクチャを維持する必要がある場合は、「somecol」列にインデックスを追加し、最初にHASHを試し、次にB-TREEインデックスを試すことができます。これらは役立つはずですが、それでもパフォーマンスは単純なホストインスタンスほど良くはありません。