0

テーブル:

  • ノード
  • data_texts
  • データプロファイル
  • data_locations
  • データプロファイル
  • データメディア
  • データ製品
  • data_metas
  • カテゴリー
  • タグ
  • カテゴリ_ノード
  • tags_nodes

この質問は一般化された質問であり、別の質問の後ろにあります

説明:

各「データ」テーブルにはnode_id、ノード テーブルの ID を参照する があります (hasMany/belongsTo 関連付け)。

「ノード」は、テレビ番組、映画、人物、記事など、何でもかまいません (すべて CMS を介して生成されるため、ユーザーは必要な「ノード」のタイプを制御できます)。

データをプルするときに、特定のフィールドに対してクエリを実行できるようにしたいと考えています。たとえば、彼らが検索を行う場合data_texts.title = '%george%'、日時フィールドを持つノードまたは日時フィールドで並べ替えるノードをプルできるようにしたいと考えていdata_locationsます。

問題は、7 つすべてのデータ テーブル (またはそれ以上) で結合を実行すると、クエリが非常に多くの結合された行にヒットしなければならないため、タイムアウトになることです (データベースがほぼ空の場合でも....全体で合計 200 行になります)。データベース)。

何をしているかに応じて、結合が必要かどうかを判断できることはわかっていますが、5 つまたは 6 つの結合 (データベースが 10,000 件以上のレコードに達すると) を使用しても、まったく機能する場合は恐ろしく遅くなります。この質問に従って、これらのテーブルで結合を行うだけで使用しているクエリが完全にタイムアウトします。

各ノードには、各データ型の複数の行を含めることができます (特に多言語の理由により)。

私は完全に打ちのめされています。全体を再構築する必要があると思うところまで来ましたが、そのための時間がありません。すべてを 1 つのテーブルにまとめることを考えましたが、方法がわかりません....など


ノード

CREATE TABLE `nodes` (
    `id` CHAR(36) NOT NULL,
    `name` VARCHAR(100) NOT NULL,
    `slug` VARCHAR(100) NOT NULL,
    `node_type_id` CHAR(36) NOT NULL,
    `site_id` CHAR(36) NOT NULL,
    `created` DATETIME NOT NULL,
    `modified` DATETIME NOT NULL,
    PRIMARY KEY (`id`),
    INDEX `nodeTypeId` (`node_type_id`),
    INDEX `slug` (`slug`),
    INDEX `nodeId` (`id`)
)
COLLATE='latin1_swedish_ci'
ENGINE=MyISAM;

データテキスト:

CREATE TABLE `data_texts` (
    `id` CHAR(36) NOT NULL,
    `title` VARCHAR(250) NULL DEFAULT NULL,
    `subtitle` VARCHAR(500) NULL DEFAULT NULL,
    `content` LONGTEXT NULL,
    `byline` VARCHAR(250) NULL DEFAULT NULL,
    `language_id` CHAR(36) NULL DEFAULT NULL,
    `foreign_key` CHAR(36) NULL DEFAULT NULL,
    `model` VARCHAR(40) NULL DEFAULT NULL,
    `node_id` CHAR(36) NULL DEFAULT NULL,
    `created` DATETIME NOT NULL,
    `modified` DATETIME NOT NULL,
    PRIMARY KEY (`id`),
    INDEX `nodeId` (`node_id`),
    INDEX `languageId_nodeId` (`language_id`, `node_id`),
    INDEX `foreignKey_model` (`foreign_key`, `model`)
)
COLLATE='utf8_general_ci'
ENGINE=MyISAM;

データプロファイル

CREATE TABLE `data_profiles` (
`id` CHAR(36) NOT NULL,
`name` VARCHAR(80) NULL DEFAULT NULL,
`email_personal` VARCHAR(100) NULL DEFAULT NULL,
`email_business` VARCHAR(100) NULL DEFAULT NULL,
`email_other` VARCHAR(100) NULL DEFAULT NULL,
`title` VARCHAR(100) NULL DEFAULT NULL,
`description` LONGTEXT NULL,
`prefix` VARCHAR(40) NULL DEFAULT NULL,
`phone_home` VARCHAR(40) NULL DEFAULT NULL,
`phone_business` VARCHAR(40) NULL DEFAULT NULL,
`phone_mobile` VARCHAR(40) NULL DEFAULT NULL,
`phone_other` VARCHAR(40) NULL DEFAULT NULL,
`foreign_key` CHAR(36) NULL DEFAULT NULL,
`model` VARCHAR(40) NULL DEFAULT NULL,
`node_id` CHAR(36) NULL DEFAULT NULL,
`language_id` CHAR(36) NULL DEFAULT NULL,
`created` DATETIME NOT NULL,
`modified` DATETIME NOT NULL,
`user_id` CHAR(36) NULL DEFAULT NULL,
PRIMARY KEY (`id`),
INDEX `nodeId` (`node_id`),
INDEX `languageId_nodeId` (`node_id`, `language_id`),
INDEX `foreignKey_model` (`foreign_key`, `model`)
)
COLLATE='latin1_swedish_ci'
ENGINE=MyISAM;

カテゴリー

CREATE TABLE `categories` (
    `id` CHAR(36) NOT NULL,
    `name` VARCHAR(100) NOT NULL,
    `node_type_id` CHAR(36) NOT NULL,
    `site_id` CHAR(36) NOT NULL,
    `slug` VARCHAR(100) NOT NULL,
    `created` DATETIME NOT NULL,
    `modified` DATETIME NOT NULL,
    PRIMARY KEY (`id`),
    INDEX `nodeTypeId` (`node_type_id`),
    INDEX `slug` (`slug`)
)
COMMENT='Used to categorize nodes'
COLLATE='utf8_general_ci'
ENGINE=MyISAM;

カテゴリ_ノード

CREATE TABLE `categories_nodes` (
    `id` CHAR(36) NOT NULL,
    `category_id` CHAR(36) NOT NULL,
    `node_id` CHAR(36) NOT NULL,
    PRIMARY KEY (`id`),
    INDEX `categoryId_nodeId` (`category_id`, `node_id`)
)
COLLATE='utf8_general_ci'
ENGINE=MyISAM;

node_tags

CREATE TABLE `node_tags` (
    `id` CHAR(36) NOT NULL,
    `name` VARCHAR(40) NOT NULL,
    `site_id` CHAR(36) NOT NULL,
    `created` DATETIME NOT NULL,
    `modified` DATETIME NOT NULL,
    PRIMARY KEY (`id`),
    INDEX `siteId` (`site_id`)
)
COLLATE='utf8_general_ci'
ENGINE=MyISAM;

nodes_node_tags

CREATE TABLE `nodes_node_tags` (
    `id` CHAR(36) NOT NULL,
    `node_id` CHAR(36) NOT NULL,
    `node_tag_id` CHAR(36) NOT NULL,
    PRIMARY KEY (`id`),
    INDEX `node_id_node_tag_id` (`node_id`, `node_tag_id`)
)
COLLATE='utf8_general_ci'
ENGINE=MyISAM;

MySQL:

SELECT `Node`.`id`, `Node`.`name`, `Node`.`slug`, `Node`.`node_type_id`, `Node`.`site_id`, `Node`.`created`, `Node`.`modified`
FROM `mysite`.`nodes` AS `Node`
LEFT JOIN `mysite`.`data_date_times` AS `DataDateTime` ON (`DataDateTime`.`node_id` = `Node`.`id`)
LEFT JOIN `mysite`.`data_locations` AS `DataLocation` ON (`DataLocation`.`node_id` = `Node`.`id`)
LEFT JOIN `mysite`.`data_media` AS `DataMedia` ON (`DataMedia`.`node_id` = `Node`.`id`)
LEFT JOIN `mysite`.`data_metas` AS `DataMeta` ON (`DataMeta`.`node_id` = `Node`.`id`)
LEFT JOIN `mysite`.`data_profiles` AS `DataProfile` ON (`DataProfile`.`node_id` = `Node`.`id`)
LEFT JOIN `mysite`.`data_products` AS `DataProduct` ON (`DataProduct`.`node_id` = `Node`.`id`)
LEFT JOIN `mysite`.`data_texts` AS `DataText` ON (`DataText`.`node_id` = `Node`.`id`)
WHERE 1=1
GROUP BY `Node`.`id`

EXPLAIN クエリ

4

2 に答える 2

0

まず、MyISAM ではなく、InnoDB を試してください。

次に、group by を削除し、グループの実行状況と関連する行数を確認します。それほど多くはないはずですが、興味深いものです。

ノードの 'nodeId' インデックスは必要ありません (既に主キーとして持っているため)。繰り返しますが、違いはありません。

where句は関係ありません。なんらかの方法で効果なく削除できます。

第三に、まあ、何かがひどく壊れています。

プロファイリングを開始する方法 (例: http://dev.mysql.com/doc/refman/5.0/en/show-profile.html ) をざっと見て、プロファイル コマンドを実行して、常にどこに行っているかを確認します。何かが壊れていることをすぐに示さない場合は、ここに投稿してください。

于 2012-09-19T12:41:16.093 に答える
0

残念ながら、私は現在、テストを行うことができる立場にありません。ちょっとアイデアを出してみます。後でいくつかのテストを行うことができるかもしれません。

  • さまざまな照合を疑ってください。
  • あなたのIDのいくつかは役に立たない. たとえば、列category_nodes.idを削除し、代わりに{category_id, node_id}に主キー制約を設定する必要があります。
  • 実行時にすべてのテーブルを結合する必要がある設計には注意してください。より良い方法があります。
  • innodb と外部キー制約を使用します。
于 2012-09-19T14:57:34.620 に答える