0

データベースにいくつかのメールを取得したいのですが、各メールにはステータスがあります。考えられるすべてのステータスは、すべての権限 (表示、編集、削除など) を持つテーブルのストックです。これらの電子メールは、サイトのアクセス許可を持つユーザーではなく、ユーザーが追加した電子メールのリストです。

テーブル構造は次のとおりです。

メールテーブル

    存在しない場合はテーブルを作成 `email__email` (
    `email_id` int(11) NOT NULL AUTO_INCREMENT,
    `created` タイムスタンプ NULL DEFAULT NULL,
    `updated` タイムスタンプ NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    `user_fk` int(11) NOT NULL,
    `status_fk` tinyint(2) NOT NULL,
    `language` enum('fr','en') COLLATE utf8_unicode_ci DEFAULT NULL,
    `email` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
    `firstName` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
    `lastName` varchar(100) COLLATE utf8_unicode_ci DEFAULT NULL,
    `companyName` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
    `gender` enum('f','m') COLLATE utf8_unicode_ci DEFAULT NULL,
    主キー (`email_id`),
    UNIQUE KEY `user_email` (`user_fk`,`email`),
    KEY `user_fk` (`user_fk`),
    KEY `created` (`created`),
    KEY `status_fk` (`status_fk`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=3031492 ;

ステータス表

    CREATE TABLE IF NOT EXISTS `email__status` (
    `status_id` int(11) NOT NULL AUTO_INCREMENT,
    `name_fr` varchar(50) COLLATE utf8_unicode_ci DEFAULT NULL,
    `name_en` varchar(50) COLLATE utf8_unicode_ci DEFAULT NULL,
    `description_fr` varchar(150) COLLATE utf8_unicode_ci DEFAULT NULL,
    `description_en` varchar(150) COLLATE utf8_unicode_ci DEFAULT NULL,
    `permShow` tinyint(1) NOT NULL DEFAULT '0',
    `permSend` tinyint(1) NOT NULL DEFAULT '0',
    `permEdit` tinyint(1) NOT NULL DEFAULT '0',
    `permDelete` tinyint(1) NOT NULL DEFAULT '0',
    `permImport` tinyint(1) NOT NULL DEFAULT '0',
    主キー (`status_id`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=7 ;

EXPLAIN を使用した遅いクエリを次に示します。

    SELECT EE.*、ES.name_fr AS statusName、ES.description_fr AS statusDescription、ES.permShow、ES.permSend、ES.permEdit、ES.permDelete、ES.permImport
    , (SELECT GROUP_CONCAT(CONVERT(CONCAT(GC.name, '~', GC.group_id), CHAR(255)) SEPARATOR ',') FROM `group` GC INNER JOIN group_email GEC ON GEC.group_fk = GC.group_id WHERE GEC.email_fk = EE.email_id AND GC.deleted = 0) グループとして
    FROM `email__email` EE
    内部結合 email__status ES ON EE.status_fk = ES.status_id
    ここで 1 = 1
    AND EE.user_fk = 54
    AND ES.permShow = 1
    ORDER BY EE.email_id DESC LIMIT 15


    EXTRA ID KEY KEY_LEN POSSIBLE_KEYS REF ROWS SELECT_TYPE テーブルタイプ
    一時的な使用; filesort の使用 1 user_email 4 user_email,user_fk,status_fk const 180681 PRIMARY EE ref
    where を使用します。結合バッファの使用 1 [空文字列] [空文字列] PRIMARY [空文字列] 6 PRIMARY ES ALL
    インデックスの使用 2 email_fk 4 group_email,group_fk,email_fk mailing_dev.EE.email_id 1 DEPENDENT SUBQUERY GEC ref
    where 2 PRIMARY 4 PRIMARY mailing_dev.GEC.group_fk 1 DEPENDENT SUBQUERY GC eq_ref の使用

EXPLAIN を使用した高速クエリを次に示します。

    EE.* を選択
    , (SELECT GROUP_CONCAT(CONVERT(CONCAT(GC.name, '~', GC.group_id), CHAR(255)) SEPARATOR ',') FROM `group` GC INNER JOIN group_email GEC ON GEC.group_fk = GC.group_id WHERE GEC.email_fk = EE.email_id AND GC.deleted = 0) グループとして
    FROM `email__email` EE
    ここで 1 = 1
    AND EE.user_fk = 54
    AND EXISTS(select permShow FROM email__status WHERE status_id = EE.status_fk AND permShow = 1)
    ORDER BY EE.email_id DESC LIMIT 15


    EXTRA ID KEY KEY_LEN POSSIBLE_KEYS REF ROWS SELECT_TYPE テーブルタイプ
    where の使用 1 PRIMARY 4 user_email,user_fk [空の文字列] 270 PRIMARY EE インデックス
    where 3 PRIMARY 4 PRIMARY mailing_dev.EE.status_fk 1 DEPENDENT SUBQUERY email__status eq_ref の使用
    インデックスの使用 2 email_fk 4 group_email,group_fk,email_fk mailing_dev.EE.email_id 1 DEPENDENT SUBQUERY GEC ref
    where 2 PRIMARY 4 PRIMARY mailing_dev.GEC.group_fk 1 DEPENDENT SUBQUERY GC eq_ref の使用

両方のクエリには大きな違いがありますが、2 つ目のクエリでは、フェッチする必要がある 2 つの重要な列が得られません。結合のようにサブクエリを実行してそれらを取得できますが、それでも、それぞれに多くのサブクエリを作成したくありません...これを改善するアイデアはありますか?

ありがとう

4

1 に答える 1

0

email__email.status_fktinyint ですemail__status.status_idが、int(11) です。

これはおそらくあなたのINNER JOINを汚しています。いずれかのデータ型を変更して、再試行してください。

于 2012-06-28T19:37:48.397 に答える