1

たくさんのフィルターを使ってサイトを構築しています。検索をクリック/絞り込むたびに、すべてのフィルターのすべてのカウンターが再計算されます。クリックするたびに、約50カウントのクエリを実行してすべてのフィルターを再カウントしているため、ここで問題が発生していることに気付きました。一度に多くのユーザーがサイトを使用している場合、これによりデータベースにかなりの負荷がかかります。

より多くのコンテキストが必要な場合、フィルターカウンターは次のようになります:http ://screencast.com/t/3bxrWTAtm

これらのカウントを最適化するための最良の方法は何ですか?memcacheを使用することもできますが、新しいリストが表示される可能性があるため、最大で約15〜30分間キャッシュする必要があります。

COUNTクエリの1つの例を次に示します。

SELECT COUNT(id) AS numOfRows FROM (SELECT `id`, `theLatitude`, `theLongitude`, ( 3959 * acos( cos( radians(45.5086699) ) * cos( radians( theLatitude ) ) * cos( radians( theLongitude ) - radians(-73.5539925) ) + sin( radians(45.5086699) ) * sin( radians( theLatitude ) ) ) ) AS distance  FROM `housing` WHERE  (`elevator` = '1') AND ( `property-type` = 'loft' )  HAVING distance < 75) AS `newid`

ハウジングテーブルは次のようになります。

CREATE TABLE IF NOT EXISTS `housing` (
`id` varchar(10) NOT NULL,
`date` datetime NOT NULL,
`user` varchar(20) NOT NULL,
`email` varchar(50) NOT NULL,
`title` varchar(60) NOT NULL,
`address` varchar(120) DEFAULT NULL,
`formatted_address` varchar(120) NOT NULL,
`theLatitude` double DEFAULT NULL,
`theLongitude` double DEFAULT NULL,
`property-type` varchar(20) NOT NULL,
`square-feet` int(9) DEFAULT NULL,
`bathrooms` double NOT NULL DEFAULT '0',
`bedrooms` int(2) NOT NULL DEFAULT '0',
`price` int(10) DEFAULT NULL,
`priceUSD` int(10) NOT NULL,
`currency` varchar(3) DEFAULT NULL,
`period` varchar(5) DEFAULT NULL,
`lease-terms` varchar(20) NOT NULL,
`available-from` date NOT NULL,
`contactName` varchar(30) NOT NULL,
`contactPhone1` varchar(30) NOT NULL,
`contactPhone2` varchar(30) NOT NULL,
`description` text NOT NULL,
`cats` tinyint(1) NOT NULL DEFAULT '0',
`small-dogs` tinyint(1) NOT NULL DEFAULT '0',
`small-pets` tinyint(1) NOT NULL DEFAULT '0',
`big-dogs` tinyint(1) NOT NULL DEFAULT '0',
`alarm-system` tinyint(1) NOT NULL DEFAULT '0',
`air-conditioning` tinyint(1) NOT NULL DEFAULT '0',
`balcony` tinyint(1) NOT NULL DEFAULT '0',
`carpet-floors` tinyint(1) NOT NULL DEFAULT '0',
`dishwasher` tinyint(1) NOT NULL DEFAULT '0',
`electricity` tinyint(1) NOT NULL DEFAULT '0',
`fireplace` tinyint(1) NOT NULL DEFAULT '0',
`furniture` tinyint(1) NOT NULL DEFAULT '0',
`heating` tinyint(1) NOT NULL DEFAULT '0',
`high-ceilings` tinyint(1) NOT NULL DEFAULT '0',
`hot-water` tinyint(1) NOT NULL DEFAULT '0',
`natural-gas` tinyint(1) NOT NULL DEFAULT '0',
`spa-hot-tub` tinyint(1) NOT NULL DEFAULT '0',
`refrigerator` tinyint(1) NOT NULL DEFAULT '0',
`stove` tinyint(1) NOT NULL DEFAULT '0',
`storage-space` tinyint(1) NOT NULL DEFAULT '0',
`walk-in-closets` tinyint(1) NOT NULL DEFAULT '0',
`washer-dryer` tinyint(1) NOT NULL DEFAULT '0',
`doorman` tinyint(1) NOT NULL DEFAULT '0',
`elevator` tinyint(1) NOT NULL DEFAULT '0',
`health-facilities` tinyint(1) NOT NULL DEFAULT '0',
`inside-parking` tinyint(1) NOT NULL DEFAULT '0',
`laundry-facilities` tinyint(1) NOT NULL DEFAULT '0',
`outside-parking` tinyint(1) NOT NULL DEFAULT '0',
`pool-sauna` tinyint(1) NOT NULL DEFAULT '0',
`wheelchair-access` tinyint(1) NOT NULL DEFAULT '0',
`authnumber` varchar(15) NOT NULL,
`validated` tinyint(1) NOT NULL DEFAULT '0',

主キー(id))ENGINE = MyISAM DEFAULT CHARSET = latin1;

ユーザーがフィルタリングできる50以上のフィールドがあります。

私を正しい方向に向けるために何かをいただければ幸いです。

4

3 に答える 3

0

私は過去に、カテゴリと製品を使用してWebサイトに対して同様のことを行いました。私のアプローチは、最初にフィルターのグループごとに1つのアプリケーション呼び出しを作成することでした。つまり、例として機能のリストを取得するための1回の呼び出しです。

次に、その呼び出しをアプリケーション/Webコードにキャッシュする必要がありますアプリケーションまたはアプリケーションを強化するサービスからの関数呼び出しをキャッシュできます。たとえば、関数 "getListingFeatures()"がある場合、その関数をMemcachedに2分間キャッシュします。有効期限が切れると、もちろんデータベースに移動し、キャッシュに再度ロードされます。

有効期限を確実に低く設定できます。

また、「Thundering Herds」(http://en.wikipedia.org/wiki/Thundering_herd_problem)を回避するために、有効期限をかなりランダムにすることを検討してください。

それを維持し、Memcachedを使用することを強くお勧めします。

于 2013-01-14T03:23:07.320 に答える
0

まず、Explainクエリで使用して、mysqlが調べなければならない行数を確認します。舞台裏で何が起こっているのかを理解するようにしてください。

次に、可能であれば、Joinネストされたクエリの代わりに使用します。これはmysqlでははるかに軽量です。

3番目に、フィルター列でさまざまなインデックスを試してください。

編集:ビルカーウィンは私にインデックスの1,2,3ルールを教えてくれました。つまりWHERE、、、。ORDER BY_ SELECTWHEREステートメントの列は、通常、インデックスを追加するためにも最も重要です。

さて、そのような集中的な計算を使用するクエリでは、どのインデックスが最適に機能するかはわかりません。そのため、実験を行う必要があります。

インデックスの基本については、このスライドショーをご覧ください。すべてのクレジットはビルカーウィンに行きます。

于 2013-01-14T04:07:56.447 に答える
0
  1. Explainhellohellosharpの回答で提案されているように使用してください。
  2. indexテーブルの属性に追加してみてください。
  3. Mysqlキャッシュを使用します。
  4. memcachedを使用します。強くお勧めします!
于 2013-01-14T04:20:01.063 に答える