跳转到内容
View in the app

A better way to browse. Learn more.

彼岸论坛

A full-screen app on your home screen with push notifications, badges and more.

To install this app on iOS and iPadOS
  1. Tap the Share icon in Safari
  2. Scroll the menu and tap Add to Home Screen.
  3. Tap Add in the top-right corner.
To install this app on Android
  1. Tap the 3-dot menu (⋮) in the top-right corner of the browser.
  2. Tap Add to Home screen or Install app.
  3. Confirm by tapping Install.
欢迎抵达彼岸 彼岸花开 此处谁在 -彼岸论坛

[问与答] mysql 小白请教大佬一个问题

发表于

首先 mysql 环境是我购买的腾讯云学生 TDSQL,1c1g60G 。 最开始我创建了一张表:

-- auto-generated definition
create table phishtank_database
(
    id                int auto_increment
        primary key,
    phish_id          int                                 not null,
    url               varchar(2048)                       not null,
    url_sha256        char(64)                            not null,
    phish_detail_url  varchar(2048)                       not null,
    submission_time   datetime                            not null,
    verified          varchar(255)                        not null,
    verification_time datetime                            not null,
    online            varchar(255)                        not null,
    target            varchar(255)                        not null,
    created_at        timestamp default CURRENT_TIMESTAMP not null,
    etag              varchar(255)                        not null,
    constraint url_sha256_unique
        unique (url_sha256)
)
    charset = utf8mb4;

因为为了保证 url 是唯一的,给 url_sha256 加了唯一约束,我是有一个 github action 定时抓取最新的 url 到数据库中的,已经执行了好几个月没有问题。但是突然最近疯狂报错,我一看是现在批量 insert 的速度太慢。我的批量 insert 模板就是:

insert ignore into phishing_intelligence.phishtank_database (phish_id, url, url_sha256, phish_detail_url, submission_time , verified, verification_time, online, target, etag) values (?, ?, ?, ?, ? , ?, ?, ?, ?, ?),(?, ?, ?, ?, ? , ?, ?, ?, ?, ?),......

我测试了单个 insert into 需要 2s 出头,有一次批量插入 300 余条记录花费了 18min 。 然后我看腾讯云控制台中有一次慢 sql 执行竟然扫描了 7 亿多行。

我很自然会想到由于是需要检查唯一索引 url_sha256 每次插入都需要全表扫描+重建索引。随着数据量增加(但其实现在这个表中也只有 10w 出头的行)执行时间逐渐变长。而且我现在手动执行一次上述 instert 语句然后在实时监控中看到每秒的 innodb_rows_read 在 10w+。

但是我转头一想,既然 url_sha256 是唯一索引,那我这条语句岂不是逻辑上可以分两步:

  1. 先检查本条 url_sha256 是否存在,存在就直接 ignore (我理解的因为有索引的存在这个过程应该很快)
  2. 如果不存在就直接在表尾插入新数据。(因为我的主键是自增 ID ,按照聚簇的话是不是新数据就追加在最后面?) 如果按照上述逻辑的话是不是就不应该有大量全表扫描的操作了?难道是插入完毕后重建索引的操作需要大量的全表扫描?

原谅我数据库知识太欠缺了,我知道上面很多推测只是我片面认识的结果,希望能有大佬帮忙解答一下:

  1. 上面的逻辑是不是存在问题
  2. 是不是我购买的低配置的 tqsql 硬件配置制约了插入的速度?必须提升硬件配置才有可能解决
  3. 大佬有没有其他解决方案可以赐教

Featured Replies

No posts to show

创建帐户或登录来提出意见

Configure browser push notifications

Chrome (Android)
  1. Tap the lock icon next to the address bar.
  2. Tap Permissions → Notifications.
  3. Adjust your preference.
Chrome (Desktop)
  1. Click the padlock icon in the address bar.
  2. Select Site settings.
  3. Find Notifications and adjust your preference.