从平坦的CSV输入文件中标准化DB以获得更高的性能?

时间:2017-06-21 13:12:59

标签: mysql csv

非常感谢你的帮助!我试图打破我的问题:

背景

我试图了解我们的文件服务器如何随着时间的推移而增长,我想通过收集使用数据和运行统计信息(用户所需的空间,最大的目录,增长最快的目录等)来实现这一点。 / p>

为了收集一个快照,我编写了一个脚本,该脚本遍历目录树并使用以下标题将数据写入CSV文件:
SCANID,SCANDATE,DIR,FILENAME,SIZE,MODTIME,ATIME,OWNER

SCANID:随机uuid4字符串标识扫描
SCANDATE:扫描开始的日期(不一定是与SCANID的1:1关系)

挑战

我可以将它导入到MySQL中的等效表中,但我很快就遇到了性能问题。我们的系统上有数百万个文件。 MySQL表如下:

CREATE TABLE IF NOT EXISTS FILES (
    SCANID VARCHAR(40),
    SCANDATE DATE,
    DIRECTORY VARCHAR(700),
    FILENAME VARCHAR(300),
    SIZE BIGINT,
    ATIME DATETIME,
    MODTIME DATETIME,
    OWNER VARCHAR(50)
);

我相信DIRECTORY和FILENAME占用了很大一部分空间,特别是如果你为我的每次扫描都不断重复这些空间。

我想对数据做的分析如下:
 *所需磁盘总空间随时间增长的速度有多快  *哪个用户占用的空间最多 - SELECT OWNER, SUM(SIZE) FROM FILES GROUP BY OWNER ORDER BY SUM(SIZE) DESC;
 *哪些目录随时间增长最快
 *哪些用户随着时间的推移生成大部分数据

解决方法

创建三个表,只收集更改的数据(我只想知道尺寸是否发生变化,只保留最新的所有者,adate和mdate)

表1:FILES

CREATE TABLE IF NOT EXISTS FILES (
    SCAN_ID INT,
    DIR VARCHAR(700) DEFAULT NULL,
    FILENAME VARCHAR(500) DEFAULT NULL,
    ATIME DATETIME DEFAULT NULL, 
    MODTIME DATETIME DEFAULT NULL,
    OWNER VARCHAR(50) DEFAULT NULL, 
    PRIMARY KEY (DIR, FNAME)
);

表2:尺寸
SCAN_ID,FILE_ID,SIZE

表3:SCANDATES
SCAN_ID,SCANDATE

为了实现这一目标,我将完整的CSV文件加载到与CSV文件具有相同结构的临时表(FILES_IMPORT)中,然后将日期分发到相应的表中。

因此,表1应该包含我见过的所有文件名:

INSERT INTO FILES (DIR, FNAME, OWNER, ATIME, MODTIME)
    SELECT DIR, FNAME, OWNER, ATIME, MODTIME FROM FILES_IMPORT
    ON DUPLICATE KEY UPDATE
        OWNER=VALUES(OWNER),
        ATIME=VALUES(ATIME),
        MODTIME=VALUES(MODTIME);

As(DIR,FILENAME)是主键,这满足了每个文件只有一个条目的要求。

问题

但是,我不知道如何更新SIZES表。我不希望将(DIR,FNAME)作为PRIMARY KEY,因为这不会使DB更小或更快。除此之外,我不知道我的方法是否合理。

非常感谢你的帮助。

1 个答案:

答案 0 :(得分:1)

我只想写一些没有特别顺序的想法。

您尚未描述针对此数据运行的任何特定SQL查询,因此我们无法制定有关索引或其他优化的策略。这些很重要,而且通常比数据的大小更重要。

如果您正在执行需要扫描所有行的复杂报表查询,则可能需要使用面向列的存储引擎来获得更好的性能。同样,这取决于您需要优化的查询类型。

我不知道为什么你有SCAN_ID(4个字节),因为它有1:1的关系(顺便说一下,请不要使用术语“{{ 3}}“当你的意思是”关系“)。如果您不使用SCAN_ID,则可以使用SCAN_DATE,FILE_ID作为SIZES表的主键。

您可以使用文件3 bytes作为文件的主键。虽然inode编号在不同的文件系统上是独立编号的,但如果你的服务器安装了多个文件系统,你也必须在主键中包含一些文件系统的标识符。