2

在这里,我提出了一种从日志表中按天和平台检索 MAU 的方法。
这是通过在过程中使用临时表来完成的。
任何人都知道查询这个的最快方法吗?

/* CREATE LOG TABLE EXAMPLE */

CREATE TABLE TEST_LOG (
       ID INTEGER UNSIGNED NOT NULL AUTO_INCREMENT
     , DTIME DATETIME
     , USERID BIGINT UNSIGNED NOT NULL
     , PLATFORM CHAR(25) NULL
     , PRIMARY KEY (ID)
)ENGINE=InnoDB  DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;


/* CREATE PROCEDURE TO ADD SOME TEST DATA INTO TEST_LOG */

DROP PROCEDURE IF EXISTS ADD_TEST_DATA;

DELIMITER |
CREATE PROCEDURE ADD_TEST_DATA(DATE_START DATETIME, DATE_END DATETIME)
BEGIN
    DECLARE T_PRAND INTEGER DEFAULT NULL;
    DECLARE T_COUNT INTEGER DEFAULT NULL;
    DECLARE T_URAND INTEGER DEFAULT NULL;
    DECLARE T_PLATF INTEGER DEFAULT NULL;
    DECLARE T_PLATN CHAR(25) DEFAULT NULL;
    WHILE DATE_START <= DATE_END DO 
            SELECT FLOOR(1+RAND()*10) INTO T_PRAND FROM DUAL; /* 1-10 RANDOM LOGS FOR EACH DAY */
            SET T_COUNT = 0;
            WHILE T_COUNT <= T_PRAND DO
                SELECT FLOOR(1+RAND()*1000) INTO T_URAND FROM DUAL;  /* RANDOM USER */
                SELECT FLOOR(1+RAND()*5)    INTO T_PLATF FROM DUAL;  /* RANDOM PLATFORM */
                CASE T_PLATF
                    WHEN 1 THEN SET T_PLATN = 'WEB';
                    WHEN 2 THEN SET T_PLATN = 'FACEBOOK';
                    WHEN 3 THEN SET T_PLATN = 'IPHONE';
                    WHEN 4 THEN SET T_PLATN = 'IPAD';
                    WHEN 5 THEN SET T_PLATN = 'ANDROID';
                    ELSE
                        BEGIN
                        END;
                END CASE;
                INSERT INTO TEST_LOG (DTIME,USERID,PLATFORM) VALUES (DATE_START, T_URAND, T_PLATN);
                SET T_COUNT = T_COUNT+1;
            END WHILE;
        SET DATE_START = DATE_ADD(DATE_START, INTERVAL 1 DAY);
    END WHILE;
END 
|
;

CALL ADD_TEST_DATA('2013-01-01 00:00:00', '2013-03-25 23:59:59'); /* SAMPLE DATE CREATION */


/* CREATE PROCEDURE TO CALCULATE MAU */

DROP PROCEDURE IF EXISTS MAU;

DELIMITER |
CREATE PROCEDURE MAU(DATE_START DATETIME, DATE_END DATETIME)
BEGIN
    DECLARE T_DTIME     DATETIME    DEFAULT NULL;
    DECLARE T_ATOTAL        INTEGER     DEFAULT NULL;   
    DECLARE T_WEB           CHAR(10)    DEFAULT NULL;
    DECLARE T_FACEBOOK      CHAR(10)    DEFAULT NULL;
    DECLARE T_IPHONE        CHAR(10)    DEFAULT NULL;
    DECLARE T_IPAD          CHAR(10)    DEFAULT NULL;
    DECLARE T_ANDROID       CHAR(10)    DEFAULT NULL;   
    DECLARE T_UNKNOWN       CHAR(10)    DEFAULT NULL;   
    DROP TEMPORARY TABLE IF EXISTS TEMP_RESULTS;
    CREATE TEMPORARY TABLE IF NOT EXISTS TEMP_RESULTS  (
        TEMP_DTIME  DATE,
        TEMP_ATOTAL     INTEGER,        
        TEMP_WEB        CHAR(10)    DEFAULT NULL,
        TEMP_FACEBOOK   CHAR(10)    DEFAULT NULL,
        TEMP_IPHONE     CHAR(10)    DEFAULT NULL,
        TEMP_IPAD       CHAR(10)    DEFAULT NULL,
        TEMP_ANDROID    CHAR(10)    DEFAULT NULL,       
        TEMP_UNKNOWN    CHAR(10)    DEFAULT NULL    
    );  
    WHILE DATE_START <= DATE_END DO 
        SELECT DATE(DATE_START),
        COUNT( DISTINCT USERID ) AS UNIQUE_TOTAL,       
        COUNT( DISTINCT CASE WHEN PLATFORM='WEB' THEN USERID ELSE NULL END ) AS WEB,
        COUNT( DISTINCT CASE WHEN PLATFORM='FACEBOOK' THEN USERID ELSE NULL END ) AS FACEBOOK,
        COUNT( DISTINCT CASE WHEN PLATFORM='IPHONE' THEN USERID ELSE NULL END ) AS IPHONE,
        COUNT( DISTINCT CASE WHEN PLATFORM='IPAD' THEN USERID ELSE NULL END ) AS IPAD,
        COUNT( DISTINCT CASE WHEN PLATFORM='ANDROID' THEN USERID ELSE NULL END ) AS ANDROID,
        COUNT( DISTINCT CASE WHEN PLATFORM <> 'WEB' 
                              AND PLATFORM <> 'FACEBOOK'
                              AND PLATFORM <> 'IPHONE'
                              AND PLATFORM <> 'IPAD'
                              AND PLATFORM <> 'ANDROID'
                                                    THEN USERID ELSE NULL END ) AS UNKNOWN      
        INTO T_DTIME, T_ATOTAL, T_WEB, T_FACEBOOK, T_IPHONE, T_IPAD, T_ANDROID, T_UNKNOWN
        FROM TEST_LOG
        WHERE ID >= 1
        AND DTIME > DATE_START + INTERVAL -1 MONTH
        AND DTIME <= DATE_START;
        INSERT INTO TEMP_RESULTS VALUES (T_DTIME, T_ATOTAL, T_WEB, T_FACEBOOK, T_IPHONE, T_IPAD, T_ANDROID, T_UNKNOWN);
        SET DATE_START = DATE_START + INTERVAL 1 DAY;
    END WHILE;
    SELECT TEMP_DTIME AS DATE, TEMP_ATOTAL AS TOTAL_UNIQUE, TEMP_WEB AS WEB, TEMP_FACEBOOK AS FACEBOOK, 
           TEMP_IPHONE AS IPHONE, TEMP_IPAD AS IPAD, TEMP_ANDROID AS ANDROID, TEMP_UNKNOWN AS UNKNOWN 
    FROM TEMP_RESULTS;
    DROP TEMPORARY TABLE IF EXISTS TEMP_RESULTS;
END 
|
;

CALL MAU('2013-01-01 00:00:00', '2013-03-25 23:59:59'); /* QUERYING SAMPLE DATA */


任何改进表示赞赏,谢谢!

4

0 回答 0