0

mysql を使用して、他のソーシャル ネットワーキング サイトと同様に Web サイトを開発しています。

ユーザーに提案を提供したいと思います。この機能をアプリケーションに実装しましたが、動作が非常に遅いです。このプロセスでは、サーバーから結果を取得するのに 2 ~ 3 秒かかります。必要なすべてのインデックス、テーブルの関係があります。EXPLAIN コマンドを使用して理解しましたが、問題はありませんでした。その中で何が基本的な問題なのか理解できません。私を助けてください。

ここに私のテーブル構造があります: テーブル: UserMaster ~~~~~~~~~~~~~~~~~~

CREATE TABLE `UserMaster` (
        `UserID` mediumint(8) unsigned NOT NULL AUTO_INCREMENT,
    `UserName` varchar(20) DEFAULT NULL,
        `EMailID` varchar(50) DEFAULT NULL,  
    `FirstName` varchar(20) NOT NULL,  
    `LastName` varchar(20) NOT NULL,  
    `CityID` mediumint(8) unsigned DEFAULT NULL,  
    PRIMARY KEY (`UserID`),  
    UNIQUE KEY `UX_UserMaster_UserName` (`UserName`),  
    UNIQUE KEY `UX_UserMaster_EMailID` (`EMailID`),
        KEY `FK_UserMaster_CityMst_CityID_idx` (`CityID`),  
        KEY `FK_UserMaster_CountryMst_CountryID_idx` (`CountryID`),  
    CONSTRAINT `FK_UserMaster_CityMst_CityID`       
        FOREIGN KEY (`CityID`) REFERENCES `CityMst` (`CityID`)    ON DELETE NO ACTION,  
    CONSTRAINT `FK_UserMaster_CountryMst_CountryID` FOREIGN KEY CountryID REFERENCES CountryMst (CountryID) ON DELETE NO ACTION ON UPDATE CASCADE
 ) 
ENGINE=InnoDB AUTO_INCREMENT=19722 DEFAULT CHARSET=utf8$$

表 : UserFriends ~~~~~~~~~~~~~~~~~~~

CREATE TABLE `UserFriends` (
    `FriendID` mediumint(8) unsigned NOT NULL AUTO_INCREMENT,  
    `UserID` mediumint(8) unsigned NOT NULL,  
    `UserID2` mediumint(8) unsigned NOT NULL,  
    `RequestDate` timestamp NULL DEFAULT CURRENT_TIMESTAMP,  
    `Status` tinyint(3) unsigned NOT NULL DEFAULT '2',  
    `ApprovalDate` timestamp NULL DEFAULT NULL,  
    PRIMARY KEY (`FriendID`),  
    UNIQUE KEY `UX_UserFriends_UserID_UserID2` (`UserID`,`UserID2`),  
    KEY `IX_UserFriens_UserID_ApprovalStatus` (`UserID`,`ApprovalStatus`,`UserID2`,`FriendID`,`RequestDate`,`ApprovalDate`),  
    KEY `FK_UserFriends_UserMaster_UserID_idx` (`UserID`),  
    KEY `FK_UserFriends_UserMaster_UserID2_idx` (`UserID2`),  
    CONSTRAINT `FK_UserFriends_UserMaster_UserID` FOREIGN KEY (`UserID`) REFERENCES `UserMaster` (`UserID`) ON DELETE NO ACTION ON UPDATE CASCADE,

    CONSTRAINT `FK_UserFriends_UserMaster_UserID2`  FOREIGN KEY (`UserID2`)  REFERENCES `UserMaster` (`UserID`) ON DELETE NO ACTION ON UPDATE CASCADE
 ) 
    ENGINE=InnoDB AUTO_INCREMENT=50825 DEFAULT CHARSET=utf8$$

UserID と UserID2 の両方のフィールドは UserMaster.UserID にリンクされています

これが私の選択クエリです: ~~~~~~~~~~~~~~~~~~~~~~~~

SELECT
    upm.UserID,
    upm.UserName,
    upm.FirstName, 
    COALESCE(mf.TotMutualFriends,0) TotMutualFriends
FROM UserMaster upm
LEFT JOIN CityMst  ct on ct.CityID  = upm.CityID
LEFT JOIN StateMst st on st.StateID = ct.StateID
LEFT JOIN (
    SELECT uf.UserID, COUNT(1) TotMutualFriends
    FROM (
        SELECT uf.UserID, uf.UserID2, uf.ApprovalStatus
        FROM UserFriends uf
        UNION ALL
        SELECT uf.UserID2 UserID, uf.UserID UserID2, uf.ApprovalStatus
        FROM UserFriends uf
    ) uf 
    INNER JOIN ( 
        SELECT IF(uf.UserID = 1, uf.UserID2, uf.UserID) UserID2
        FROM UserFriends uf
        WHERE (uf.UserID = 1 OR uf.UserID2 = 1)
          AND uf.ApprovalStatus = 1
    ) uf1 on uf1.UserID2 = uf.UserID2
    WHERE uf.ApprovalStatus = 1 
    GROUP BY uf.UserID
) mf on mf.UserID = upm.UserID
LEFT JOIN (
    SELECT DISTINCT usar.UserID2
    FROM UserSuggAutoRejct usar
    WHERE usar.UserID = 1
    UNION 
    SELECT IF(uf.UserID = 1, uf.UserID2, uf.UserID) UserID2
    FROM UserFriends uf
    WHERE (uf.UserID = 1 OR uf.UserID2 = 1)
) usar ON usar.UserID2 = upm.UserID
WHERE upm.UserStatus IN(10,11)
  AND upm.UserID <> 1 
  AND upm.UserID NOT IN (1221,2191) 
  AND usar.UserID2 IS NULL 
ORDER BY
   (CASE WHEN COALESCE(mf.TotMutualFriends,0) > 0 THEN 0      ELSE 1    END), 
   (CASE WHEN COALESCE(mf.TotMutualFriends,0) > 0 THEN RAND() ELSE NULL END),
   (CASE upm.CityID   WHEN  1 THEN 0      ELSE    1 END), 
   (CASE upm.CityID   WHEN  1 THEN RAND() ELSE NULL END), 
   (CASE ct.StateID   WHEN  1 THEN 0      ELSE    1 END), 
   (CASE ct.StateID   WHEN  1 THEN RAND() ELSE NULL END), 
   (CASE st.CountryID WHEN 91 THEN 0      ELSE    1 END),
   (CASE st.CountryID WHEN 91 THEN RAND() ELSE NULL END)
LIMIT 10

これは非常に遅いパフォーマンスです。進化するのに2~3秒かかります。

4

1 に答える 1

0

リレーショナル データベースは、ソーシャル ネットワーキング サイトには適していない可能性があります。テーブルの結合が非常に遅いため、他のno-sqlデータベース(NoSqlタイプのデータベース)を使用してみてください。それでも mysql の使用を主張する場合は、クエリにあまり参加しないようにしてください。

もしあれば、私の悪い英語でごめんなさい。

于 2013-04-09T10:41:03.070 に答える