Argodb所有的写操作都会在底层写入一个新的文件,而不是写入已有文件中。
举例:insert操作生成base文件,
1)update/delete操作生成delta文件,删除表中数据时,并不会直接删除数据文件。而是新增一条带有“delete”标记的记录,记录是和原记录存在放相同目录下;当读取数据时,通过“delete”标记识别记录已被删。更新操作可能是插入一条到base文件,再插入一条带有“delete”标记的记录到delta文件。Compact Service 会定期进行合并小文件,这时候才会真正的从磁盘中删除记录
2)当进行频繁的小数据量的写入操作,会导致出现大量的base/delta文件,并且内容很少(KB级别)
小文件过多可能导致如下问题:
1.IO开销大,影响性能
2.shiva tserver启动慢,内存占用高,甚至崩溃
3.argodb server 内存占用过高
ArgoDB的compact操作的主要目的是为了减少小文件数量,但是跨分区不能compact。
对开发者来说,主要避免像TP库一样高频的做单条数据插入,这样会导致短时间内大量小文件。官方在5.2.2的文档建议是:
DML
-
避免一次更新或删除大批量数据(例如大于 50,000 条),可分批执行。
-
单条语句仅更新一个表,避免更新多个表。
-
INSERT 语句需指定具体的字段。
-
INSERT/DELETE 语句的优化规则为操作粒度小(不超过 100 条),具有明确的 WHERE 条件。
-
INSERT 语句使用 BATCH 提交时(例如 INSERT INTO table_name VALUES(),(),()… ),应控制 VALUE 数量。
-
SQL 语句在程序中传入的参数值类型和数据库中该字段的类型相同,避免发生隐式类型转换。
-
DQL
-
在使用 SELECT 语句时,指定要查询的字段,避免使用 SELECT *,降低网络传输和存储 I/O 消耗的时间。
-
通过客户端(如 JDBC)操作数据库时,使用 prepared statement 避免 SQL 注入并提升性能。
-
避免或减少在核心业务的 SQL 语句中使用复杂查询,便于业务理解,同时充分利用多核 CPU 提升性能。
-
无去重需求时,优先使用 UNION ALL 来代替 UNION,提升查询效率。
-
使用 COUNT(*) 来代替 COUNT(列名),避免漏统计列为 NULL 值的行。
-
包含 DISTINCT、ORDER BY、GROUP BY 子句的查询,将中间结果集控制在 10000 行以内,
-
避免使用读锁,以免事务过大引发锁等待,从而影响业务。
-
避免跨数据库的 JOIN 操作,从而降低数据库间的耦合。
-
减少或避免排序,提升 SQL 执行效率。
-
减少或避免使用 IN 操作,可改写为 JOIN 操作。