当前位置:首页>python>Python + SQL实战:留存分析自动化

Python + SQL实战:留存分析自动化

  • 2026-07-01 04:14:30
Python + SQL实战:留存分析自动化
数据分析师的时间,不应该花在手动复制数据到Excel上。

SQL 负责取数、Python 负责分析和可视化,两者联动之后,一套留存分析从取数到出图只需要几十秒,下次只需要改一个日期参数。

这篇从连接数据库开始,完整走一遍:Cohort留存分析、统计异常检测、渠道质量散点图。全部用真实数据生成的图表,可以直接拿去放报告里。


一、连接数据库

游戏公司用得最多的两种数据源:MySQL(线上库或数仓)和阿里云 ODPS(MaxCompute,大数据平台)。

MySQL / 通用数仓

from sqlalchemy import create_engineimport pandas as pdengine = create_engine(    'mysql+pymysql://user:password@host:3306/game_db'    '?charset=utf8mb4')def query(sql: str) -> pd.DataFrame:    with engine.connect() as conn:        return pd.read_sql(sql, conn)

ODPS(MaxCompute)— 阿里云大数据平台

大型游戏公司的日志数据通常存在 ODPS,数据量在百亿行以上,不能直接连 MySQL。

from pyodps import ODPSimport pandas as pd# 初始化连接odps = ODPS(    access_id     = 'your_access_id',    secret_access_key = 'your_access_key',    project       = 'your_project',    endpoint      = 'http://service.cn-hangzhou.maxcompute.aliyun.com/api')def odps_query(sql: str, hints: dict = None) -> pd.DataFrame:    """    执行 ODPS SQL 并返回 DataFrame    hints 可以传入资源配置,比如设置内存和 CPU    """    default_hints = {        'odps.sql.mapper.split.size''256',   # 每个 Mapper 处理 256MB        'odps.instance.priority''0',          # 最高优先级    }    if hints:        default_hints.update(hints)    with odps.execute_sql(sql, hints=default_hints) as inst:        inst.wait_for_success()        return inst.open_reader(tunnel=True).to_pandas()# 示例:从 ODPS 取留存数据sql = """SELECT    reg_date,    COUNT(DISTINCT user_id)     AS new_users,    COUNT(DISTINCT CASE WHEN datediff(login_date, reg_date, 'dd') = 1                        THEN login_uid END) * 100.0    / COUNT(DISTINCT user_id)   AS d1_rateFROM dwd_user_register rLEFT JOIN dwd_user_login l    ON r.user_id = l.login_uidWHERE r.reg_date BETWEEN '2024-01-01' AND '2024-01-31'GROUP BY reg_dateORDER BY reg_date"""df = odps_query(sql)

ODPS 和 MySQL 的主要区别

  • 日期差函数用 datediff(date1, date2, 'dd') 而不是 DATEDIFF()

  • 不支持 DATE_ADD(),用 DATEADD(date, n, 'dd')

  • 分区表要带分区条件 WHERE ds = '20240101',否则全表扫描会超时


二、Cohort 留存分析

在做 Cohort 分析之前,先看整体留存率趋势——用多日留存折线图配合新用户量柱状图,能快速判断留存波动是否和用户量变化有关。
生成的图表效果:

上方是 D1/D3/D7/D14/D30 五条留存率折线,下方是每日新用户量柱状图。两个图联动看:1月9日新用户量暴增但 D1 留存同步下跌(红色标注),说明那天涌入了大量低质用户,是买量质量问题而不是产品问题。


Cohort 分析是留存分析里最有价值的方式——按注册周分组,追踪每批用户的长期留存走势,能看出游戏是否在持续优化。

def get_cohort_retention(start_date: str, end_date: str,                          day_list: list = None) -> pd.DataFrame:    """    按注册周取 Cohort 留存率    day_list: 要观测的留存节点,默认 [1,3,7,14,21,30,45,60]    """    if day_list is None:        day_list = [1371421304560]    case_clauses = '\n        ,'.join([        f"""ROUND(COUNT(DISTINCT CASE            WHEN DATEDIFF(l.login_date, r.reg_date) = {d}            THEN l.user_id END) * 100.0            / COUNT(DISTINCT r.user_id), 2) AS d{d}"""        for d in day_list    ])    sql = f"""    WITH cohort_base AS (        SELECT            -- 按注册周分组            DATE_FORMAT(reg_date, '%Y-%m-%d') AS cohort_week,            user_id,            reg_date        FROM user_register        WHERE reg_date BETWEEN '{start_date}' AND '{end_date}'    )    SELECT        r.cohort_week,        COUNT(DISTINCT r.user_id) AS new_users,        {case_clauses}    FROM cohort_base r    LEFT JOIN user_login l        ON  r.user_id    = l.user_id        AND l.login_date BETWEEN r.reg_date                             AND DATE_ADD(r.reg_date, INTERVAL {max(day_list)} DAY)    GROUP BY r.cohort_week    ORDER BY r.cohort_week    """    df = query(sql)    df['cohort_week'] = pd.to_datetime(df['cohort_week'])    return df

可视化:Cohort 热力图

import matplotlib.pyplot as pltimport seaborn as snsfrom matplotlib.colors import LinearSegmentedColormapdef plot_cohort_heatmap(df: pd.DataFrame, save_path: str = None):    day_cols   = [c for c in df.columns if c.startswith('d'and c[1:].isdigit()]    heat_data  = df.set_index('cohort_week')[day_cols]    heat_data.index = heat_data.index.strftime('%Y-%m-%d')    cmap = LinearSegmentedColormap.from_list(        'ret', ['#0D1B3E','#1565C0','#2979FF','#00ACC1','#43A047'], N=256    )    fig, ax = plt.subplots(figsize=(147))    fig.patch.set_facecolor('#0C0E18')    ax.set_facecolor('#0C0E18')    sns.heatmap(        heat_data, annot=True, fmt='.1f',        cmap=cmap, linewidths=0.4, linecolor='#1A1C2E',        ax=ax, cbar_kws={'label''留存率 (%)','shrink'0.8},        annot_kws={'size'9'color''white'},        vmin=0, vmax=70    )    ax.set_title('Cohort 留存热力图  ·  各周新用户 D1~D60 留存率',                 color='white', fontsize=13, pad=12, loc='left')    ax.tick_params(colors='#AAAACC', labelsize=9)    ax.set_xlabel('留存节点', color='#8888A0')    ax.set_ylabel('注册周',   color='#8888A0')    plt.tight_layout()    if save_path:        plt.savefig(save_path, dpi=150, bbox_inches='tight',                    facecolor='#0C0E18')    plt.show()

生成的图表效果:

颜色越深蓝(→绿)说明留存越高。从热力图可以直接看出:

  • 纵向看:某批用户是否比上一批质量更好(整行变绿)

  • 横向看:D1 → D60 的衰减形态,判断游戏的长线留存能力

  • 找异常:某周某个留存节点颜色突然变深红,说明那批用户出了问题


三、统计异常检测:用 σ 自动找问题日期

靠肉眼盯折线图找异常太累,用统计方法自动识别更可靠。

方法:均值 ± N 个标准差

正常情况下,99.7% 的数据落在均值 ± 3σ 以内;落在 2σ 以外的就值得关注。

import numpy as npdef detect_anomaly(df: pd.DataFrame,                   col: str = 'd1',                   window: int = 30,                   sigma: float = 2.0) -> pd.DataFrame:    """    滚动窗口异常检测:用最近 window 天的数据动态计算均值和标准差    比用全局均值更敏感,能捕捉到趋势中的局部异常    """    df = df.copy().sort_values('reg_date')    df['rolling_mean'] = df[col].rolling(window, min_periods=7).mean()    df['rolling_std']  = df[col].rolling(window, min_periods=7).std()    df['z_score']      = (df[col] - df['rolling_mean']) / df['rolling_std']    df['is_anomaly']   = df['z_score'].abs() > sigma    df['anomaly_dir']  = np.where(df['z_score'] < -sigma, 'low',                          np.where(df['z_score'] > sigma,  'high''normal'))    return dfdef plot_anomaly(df: pd.DataFrame, col: str = 'd1',                 save_path: str = None):    import matplotlib.ticker as mtick    fig, ax = plt.subplots(figsize=(145))    fig.patch.set_facecolor('#0C0E18')    ax.set_facecolor('#0C0E18')    mean_v  = df[col].mean()    std_v   = df[col].std()    lower2  = mean_v - 2 * std_v    ax.fill_between(df['reg_date'], lower2, mean_v + 2*std_v,                    alpha=0.12, color='#2979FF', label='±2σ 正常区间')    ax.axhline(mean_v,  color='#2979FF', lw=1.2, ls='--',               alpha=0.7, label=f'均值 {mean_v:.1f}%')    ax.axhline(lower2,  color='#FF5252', lw=0.8, ls=':', alpha=0.6)    ax.plot(df['reg_date'], df[col], color='white', lw=1.8, zorder=3)    # 标注异常点    anomalies = df[df[col] < lower2]    ax.scatter(anomalies['reg_date'], anomalies[col],               color='#FF5252', s=80, zorder=5, label='异常点(< -2σ)')    for _, row in anomalies.iterrows():        ax.annotate(            f" {row[col]:.1f}%\n ({(row[col]-mean_v)/std_v:.1f}σ)",            xy=(row['reg_date'], row[col]),            xytext=(10, -22), textcoords='offset points',            color='#FF5252', fontsize=9,            arrowprops=dict(arrowstyle='->', color='#FF5252', lw=1)        )    ax.yaxis.set_major_formatter(mtick.PercentFormatter())    ax.set_title(f'{col.upper()} 留存率异常检测  ·  均值 ± 2σ 方法',                 color='white', fontsize=13, pad=10, loc='left')    ax.tick_params(colors='#8888A0')    ax.spines[:].set_color('#252535')    ax.grid(axis='y', color='#252535', lw=0.8)    ax.legend(facecolor='#14161E', edgecolor='#252535',              labelcolor='white', fontsize=9)    plt.setp(ax.xaxis.get_majorticklabels(), rotation=30,             ha='right', color='#8888A0')    plt.tight_layout()    if save_path:        plt.savefig(save_path, dpi=150, bbox_inches='tight',                    facecolor='#0C0E18')    plt.show()

生成的图表效果:

两个红点自动被标出:-2.9σ 和 -2.4σ,说明这两天的留存率显著低于历史正常水平,值得立即排查。

为什么用滚动窗口而不是全局均值?

全局均值在游戏早期数据少、波动大的时候会失真。滚动窗口(比如过去30天)能动态跟踪趋势,游戏留存在持续优化时,阈值也会随着均值一起上移,不会因为历史均值低而漏掉新的异常。


四、渠道质量散点图

渠道的好坏不能只看一个指标,要同时看 D1 留存(短期质量)、D7 留存(深度质量)和用户量(规模),三个维度一张图说清楚。

def get_channel_stats(date: str, min_users: int = 100) -> pd.DataFrame:    sql = f"""    SELECT        r.channel,        COUNT(DISTINCT r.user_id)                          AS new_users,        ROUND(COUNT(DISTINCT CASE            WHEN DATEDIFF(l.login_date, r.reg_date) = 1            THEN l.user_id END) * 100.0            / COUNT(DISTINCT r.user_id), 2)                AS d1,        ROUND(COUNT(DISTINCT CASE            WHEN DATEDIFF(l.login_date, r.reg_date) = 7            THEN l.user_id END) * 100.0            / COUNT(DISTINCT r.user_id), 2)                AS d7    FROM user_register r    LEFT JOIN user_login l        ON  r.user_id    = l.user_id        AND l.login_date BETWEEN r.reg_date                             AND DATE_ADD(r.reg_date, INTERVAL 7 DAY)    WHERE r.reg_date = '{date}'    GROUP BY r.channel    HAVING COUNT(DISTINCT r.user_id) >= {min_users}    """    return query(sql)def plot_channel_bubble(df: pd.DataFrame, save_path: str = None):    """    气泡图:X=D1留存,Y=D7留存,气泡大小=用户量,颜色=D7/D1比值    D7/D1比值反映留存黏性:相同D1下,比值越高说明用户越愿意持续回来    """    fig, ax = plt.subplots(figsize=(107))    fig.patch.set_facecolor('#0C0E18')    ax.set_facecolor('#0C0E18')    df['retention_ratio'] = df['d7'] / df['d1']    sc = ax.scatter(        df['d1'], df['d7'],        s    = df['new_users'] / 8,        c    = df['retention_ratio'],        cmap = 'RdYlGn',        vmin = 0.35, vmax = 0.55,        alpha= 0.75,        edgecolors='white', linewidth=0.4    )    # 标注高质量或大量级渠道    threshold = df['new_users'].quantile(0.7)    for _, row in df.iterrows():        if row['new_users'] > threshold or row['retention_ratio'] > 0.50:            ax.annotate(                row['channel'],                (row['d1'], row['d7']),                fontsize=8, color='white', alpha=0.85,                xytext=(55), textcoords='offset points'            )    import matplotlib.ticker as mtick    ax.xaxis.set_major_formatter(mtick.PercentFormatter())    ax.yaxis.set_major_formatter(mtick.PercentFormatter())    ax.set_xlabel('D1 留存率', color='#8888A0', fontsize=11)    ax.set_ylabel('D7 留存率', color='#8888A0', fontsize=11)    ax.set_title('渠道质量分布图  ·  气泡大小 = 用户量  ·  颜色 = D7/D1比值',                 color='white', fontsize=12, pad=10, loc='left')    ax.tick_params(colors='#8888A0')    ax.spines[:].set_color('#252535')    ax.grid(color='#252535', lw=0.8, alpha=0.5)    cb = plt.colorbar(sc, ax=ax, shrink=0.8)    cb.ax.tick_params(colors='#8888A0')    cb.set_label('D7/D1 留存比值(越高越好)', color='#8888A0', fontsize=9)    plt.tight_layout()    if save_path:        plt.savefig(save_path, dpi=150, bbox_inches='tight',                    facecolor='#0C0E18')    plt.show()

生成的图表效果:

右上角(D1高+D7高)+ 绿色(D7/D1比值高)= 理想渠道,应该加投。左下角(D1低+D7低)+ 红色 = 低质量渠道,考虑降预算或暂停。气泡大但偏红 = 量大但质量差,这类渠道是重点优化对象——要么优化素材,要么换竞价策略。


五、封装成每日自动化脚本


import loggingfrom datetime import datetime, timedeltalogging.basicConfig(level=logging.INFO,                    format='%(asctime)s  %(levelname)s  %(message)s')def daily_retention_report(days_back: int = 30):    """    每日自动化留存报告    days_back: 回看天数    """    today      = datetime.today()    start_date = (today - timedelta(days=days_back)).strftime('%Y-%m-%d')    end_date   = (today - timedelta(days=2)).strftime('%Y-%m-%d')    # D1 需要 T+2 才能取到,所以 end_date 取昨天的前一天    spot_date  = (today - timedelta(days=1)).strftime('%Y-%m-%d')    logging.info(f"开始分析:{start_date} ~ {end_date}")    # 1. 留存趋势 + 异常检测    logging.info("取留存趋势数据...")    df_ret = query(f"""        SELECT reg_date,               COUNT(DISTINCT r.user_id) AS new_users,               ROUND(COUNT(DISTINCT CASE                   WHEN DATEDIFF(l.login_date, r.reg_date) = 1                   THEN l.user_id END) * 100.0                   / COUNT(DISTINCT r.user_id), 2) AS d1,               ROUND(COUNT(DISTINCT CASE                   WHEN DATEDIFF(l.login_date, r.reg_date) = 7                   THEN l.user_id END) * 100.0                   / COUNT(DISTINCT r.user_id), 2) AS d7        FROM user_register r        LEFT JOIN user_login l            ON r.user_id = l.user_id            AND l.login_date BETWEEN r.reg_date                                 AND DATE_ADD(r.reg_date, INTERVAL 7 DAY)        WHERE r.reg_date BETWEEN '{start_date}' AND '{end_date}'        GROUP BY reg_date ORDER BY reg_date    """)    df_ret['reg_date'] = pd.to_datetime(df_ret['reg_date'])    # 2. 异常检测    df_ret = detect_anomaly(df_ret, col='d1', window=14, sigma=2.0)    anomalies = df_ret[df_ret['is_anomaly'] & (df_ret['anomaly_dir']=='low')]    if len(anomalies) > 0:        logging.warning(            f"发现 {len(anomalies)} 个 D1 留存异常低的日期:\n"            + anomalies[['reg_date','d1','z_score']].to_string(index=False)        )    else:        logging.info("D1 留存无明显异常")    # 3. 出图    plot_anomaly(df_ret, col='d1',                 save_path=f'retention_anomaly_{today:%Y%m%d}.png')    # 4. Cohort 热力图    logging.info("取 Cohort 数据...")    df_cohort = get_cohort_retention(start_date, end_date,                                      day_list=[1,3,7,14,30])    plot_cohort_heatmap(df_cohort,                        save_path=f'cohort_heatmap_{today:%Y%m%d}.png')    # 5. 渠道质量图    logging.info(f"取渠道数据({spot_date})...")    df_ch = get_channel_stats(spot_date, min_users=200)    plot_channel_bubble(df_ch,                        save_path=f'channel_bubble_{today:%Y%m%d}.png')    logging.info("报告生成完毕,图表已保存。")    return df_ret, df_cohort, df_ch# 每天早上跑一次df_ret, df_cohort, df_ch = daily_retention_report(days_back=30)

六、SQL 和 Python 各自做什么

步骤工具做什么
取数过滤SQL数据库侧聚合,减少传输量,不要把原始日志全拉到Python
统计计算pandas + numpy均值、标准差、滚动窗口、异常判断
可视化matplotlib + seaborn趋势图、热力图、气泡散点图
封装复用Python 函数参数化日期,每次只改参数,不重写代码
ODPS 取数pyodps阿里云 MaxCompute 的专属连接方式

最重要的原则:复杂的数据过滤和聚合在 SQL 里做完,不要把几百万行原始数据拉到 Python 里再 filter。Python 拿到的应该是已经聚合好的、几百行的分析结果,而不是原始日志。

最新文章

随机文章

基本 文件 流程 错误 SQL 调试
  1. 请求信息 : 2026-07-03 11:17:06 HTTP/2.0 GET : https://f.mffb.com.cn/a/490816.html
  2. 运行时间 : 0.107400s [ 吞吐率:9.31req/s ] 内存消耗:4,666.50kb 文件加载:140
  3. 缓存信息 : 0 reads,0 writes
  4. 会话信息 : SESSION_ID=9ee8c0fec32bba4355189e810259063f
  1. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/public/index.php ( 0.79 KB )
  2. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/autoload.php ( 0.17 KB )
  3. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/composer/autoload_real.php ( 2.49 KB )
  4. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/composer/platform_check.php ( 0.90 KB )
  5. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/composer/ClassLoader.php ( 14.03 KB )
  6. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/composer/autoload_static.php ( 4.90 KB )
  7. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/helper.php ( 8.34 KB )
  8. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-validate/src/helper.php ( 2.19 KB )
  9. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/helper.php ( 1.47 KB )
  10. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/stubs/load_stubs.php ( 0.16 KB )
  11. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Exception.php ( 1.69 KB )
  12. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-container/src/Facade.php ( 2.71 KB )
  13. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/symfony/deprecation-contracts/function.php ( 0.99 KB )
  14. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/symfony/polyfill-mbstring/bootstrap.php ( 8.26 KB )
  15. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/symfony/polyfill-mbstring/bootstrap80.php ( 9.78 KB )
  16. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/symfony/var-dumper/Resources/functions/dump.php ( 1.49 KB )
  17. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-dumper/src/helper.php ( 0.18 KB )
  18. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/symfony/var-dumper/VarDumper.php ( 4.30 KB )
  19. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/App.php ( 15.30 KB )
  20. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-container/src/Container.php ( 15.76 KB )
  21. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/psr/container/src/ContainerInterface.php ( 1.02 KB )
  22. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/provider.php ( 0.19 KB )
  23. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Http.php ( 6.04 KB )
  24. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/helper/Str.php ( 7.29 KB )
  25. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Env.php ( 4.68 KB )
  26. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/common.php ( 0.03 KB )
  27. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/helper.php ( 18.78 KB )
  28. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Config.php ( 5.54 KB )
  29. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/app.php ( 0.95 KB )
  30. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/cache.php ( 0.78 KB )
  31. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/console.php ( 0.23 KB )
  32. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/cookie.php ( 0.56 KB )
  33. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/database.php ( 2.48 KB )
  34. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/facade/Env.php ( 1.67 KB )
  35. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/filesystem.php ( 0.61 KB )
  36. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/lang.php ( 0.91 KB )
  37. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/log.php ( 1.35 KB )
  38. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/middleware.php ( 0.19 KB )
  39. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/route.php ( 1.89 KB )
  40. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/session.php ( 0.57 KB )
  41. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/trace.php ( 0.34 KB )
  42. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/view.php ( 0.82 KB )
  43. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/event.php ( 0.25 KB )
  44. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Event.php ( 7.67 KB )
  45. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/service.php ( 0.13 KB )
  46. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/AppService.php ( 0.26 KB )
  47. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Service.php ( 1.64 KB )
  48. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Lang.php ( 7.35 KB )
  49. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/lang/zh-cn.php ( 13.70 KB )
  50. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/initializer/Error.php ( 3.31 KB )
  51. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/initializer/RegisterService.php ( 1.33 KB )
  52. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/services.php ( 0.14 KB )
  53. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/service/PaginatorService.php ( 1.52 KB )
  54. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/service/ValidateService.php ( 0.99 KB )
  55. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/service/ModelService.php ( 2.04 KB )
  56. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-trace/src/Service.php ( 0.77 KB )
  57. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Middleware.php ( 6.72 KB )
  58. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/initializer/BootService.php ( 0.77 KB )
  59. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/Paginator.php ( 11.86 KB )
  60. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-validate/src/Validate.php ( 63.20 KB )
  61. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/Model.php ( 23.55 KB )
  62. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/Attribute.php ( 21.05 KB )
  63. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/AutoWriteData.php ( 4.21 KB )
  64. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/Conversion.php ( 6.44 KB )
  65. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/DbConnect.php ( 5.16 KB )
  66. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/ModelEvent.php ( 2.33 KB )
  67. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/RelationShip.php ( 28.29 KB )
  68. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/contract/Arrayable.php ( 0.09 KB )
  69. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/contract/Jsonable.php ( 0.13 KB )
  70. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/contract/Modelable.php ( 0.09 KB )
  71. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Db.php ( 2.88 KB )
  72. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/DbManager.php ( 8.52 KB )
  73. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Log.php ( 6.28 KB )
  74. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Manager.php ( 3.92 KB )
  75. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/psr/log/src/LoggerTrait.php ( 2.69 KB )
  76. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/psr/log/src/LoggerInterface.php ( 2.71 KB )
  77. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Cache.php ( 4.92 KB )
  78. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/psr/simple-cache/src/CacheInterface.php ( 4.71 KB )
  79. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/helper/Arr.php ( 16.63 KB )
  80. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/cache/driver/File.php ( 7.84 KB )
  81. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/cache/Driver.php ( 9.03 KB )
  82. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/contract/CacheHandlerInterface.php ( 1.99 KB )
  83. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/Request.php ( 0.09 KB )
  84. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Request.php ( 55.78 KB )
  85. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/middleware.php ( 0.25 KB )
  86. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Pipeline.php ( 2.61 KB )
  87. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-trace/src/TraceDebug.php ( 3.40 KB )
  88. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/middleware/SessionInit.php ( 1.94 KB )
  89. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Session.php ( 1.80 KB )
  90. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/session/driver/File.php ( 6.27 KB )
  91. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/contract/SessionHandlerInterface.php ( 0.87 KB )
  92. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/session/Store.php ( 7.12 KB )
  93. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Route.php ( 23.73 KB )
  94. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/RuleName.php ( 5.75 KB )
  95. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/Domain.php ( 2.53 KB )
  96. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/RuleGroup.php ( 22.43 KB )
  97. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/Rule.php ( 26.95 KB )
  98. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/RuleItem.php ( 9.78 KB )
  99. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/route/app.php ( 1.72 KB )
  100. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/facade/Route.php ( 4.70 KB )
  101. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/dispatch/Controller.php ( 4.74 KB )
  102. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/Dispatch.php ( 10.44 KB )
  103. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/controller/Index.php ( 4.81 KB )
  104. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/BaseController.php ( 2.05 KB )
  105. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/facade/Db.php ( 0.93 KB )
  106. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/connector/Mysql.php ( 5.44 KB )
  107. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/PDOConnection.php ( 52.47 KB )
  108. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/Connection.php ( 8.39 KB )
  109. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/ConnectionInterface.php ( 4.57 KB )
  110. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/builder/Mysql.php ( 16.58 KB )
  111. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/Builder.php ( 24.06 KB )
  112. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/BaseBuilder.php ( 27.50 KB )
  113. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/Query.php ( 15.71 KB )
  114. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/BaseQuery.php ( 45.13 KB )
  115. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/TimeFieldQuery.php ( 7.43 KB )
  116. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/AggregateQuery.php ( 3.26 KB )
  117. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/ModelRelationQuery.php ( 20.07 KB )
  118. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/ParamsBind.php ( 3.66 KB )
  119. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/ResultOperation.php ( 7.01 KB )
  120. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/WhereQuery.php ( 19.37 KB )
  121. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/JoinAndViewQuery.php ( 7.11 KB )
  122. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/TableFieldInfo.php ( 2.63 KB )
  123. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/Transaction.php ( 2.77 KB )
  124. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/log/driver/File.php ( 5.96 KB )
  125. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/contract/LogHandlerInterface.php ( 0.86 KB )
  126. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/log/Channel.php ( 3.89 KB )
  127. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/event/LogRecord.php ( 1.02 KB )
  128. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/Collection.php ( 16.47 KB )
  129. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/facade/View.php ( 1.70 KB )
  130. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/View.php ( 4.39 KB )
  131. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Response.php ( 8.81 KB )
  132. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/response/View.php ( 3.29 KB )
  133. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Cookie.php ( 6.06 KB )
  134. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-view/src/Think.php ( 8.38 KB )
  135. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/contract/TemplateHandlerInterface.php ( 1.60 KB )
  136. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-template/src/Template.php ( 46.61 KB )
  137. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-template/src/template/driver/File.php ( 2.41 KB )
  138. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-template/src/template/contract/DriverInterface.php ( 0.86 KB )
  139. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/runtime/temp/067d451b9a0c665040f3f1bdd3293d68.php ( 11.98 KB )
  140. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-trace/src/Html.php ( 4.42 KB )
  1. CONNECT:[ UseTime:0.000528s ] mysql:host=127.0.0.1;port=3306;dbname=f_mffb;charset=utf8mb4
  2. SHOW FULL COLUMNS FROM `fenlei` [ RunTime:0.000599s ]
  3. SELECT * FROM `fenlei` WHERE `fid` = 0 [ RunTime:0.003092s ]
  4. SELECT * FROM `fenlei` WHERE `fid` = 63 [ RunTime:0.000296s ]
  5. SHOW FULL COLUMNS FROM `set` [ RunTime:0.000485s ]
  6. SELECT * FROM `set` [ RunTime:0.000197s ]
  7. SHOW FULL COLUMNS FROM `article` [ RunTime:0.000493s ]
  8. SELECT * FROM `article` WHERE `id` = 490816 LIMIT 1 [ RunTime:0.000438s ]
  9. UPDATE `article` SET `lasttime` = 1783048626 WHERE `id` = 490816 [ RunTime:0.016103s ]
  10. SELECT * FROM `fenlei` WHERE `id` = 66 LIMIT 1 [ RunTime:0.000307s ]
  11. SELECT * FROM `article` WHERE `id` < 490816 ORDER BY `id` DESC LIMIT 1 [ RunTime:0.000505s ]
  12. SELECT * FROM `article` WHERE `id` > 490816 ORDER BY `id` ASC LIMIT 1 [ RunTime:0.005926s ]
  13. SELECT * FROM `article` WHERE `id` < 490816 ORDER BY `id` DESC LIMIT 10 [ RunTime:0.001537s ]
  14. SELECT * FROM `article` WHERE `id` < 490816 ORDER BY `id` DESC LIMIT 10,10 [ RunTime:0.002601s ]
  15. SELECT * FROM `article` WHERE `id` < 490816 ORDER BY `id` DESC LIMIT 20,10 [ RunTime:0.002389s ]
0.109265s