Delphi中DBExpress性能优于FireDAC吗?MySQL场景下FireDAC提速方法问询
FireDAC性能优化方案
不需要切换到DBExpress,仅通过以下简单调整即可大幅提升FireDAC性能,优化后性能普遍优于DBExpress:
一、首先优化测试代码的通用低效逻辑
你的测试代码本身有两处占比极高的性能损耗,和数据库组件无关:
- 循环内避免每次调用
FieldByName:该方法每次执行都会遍历结果集的字段列表查找对应字段,10万次循环会产生大量冗余开销。提前在循环外将字段对象存入局部变量,同时优化UI批量更新逻辑,修改后的代码示例:
var // 原有变量声明 FStregkode: TField; begin start := now; listbox1.Items.Clear; sqlq.Close; sqlq.SQLConnection:=sqlcon; sqlq.SQL.Clear; sqlq.SQL.Add('select * from forsendelser where kundenummer="test" limit '+spinedit1.Text); sqlq.Open; FStregkode := sqlq.FieldByName('stregkode'); ListBox1.Items.BeginUpdate; // 暂停列表重绘,避免单次添加触发重绘 try while not sqlq.Eof do begin listbox1.Items.Add(FStregkode.AsString ); sqlq.Next; end; finally ListBox1.Items.EndUpdate; // 恢复列表重绘 end; sqlq.Close; n :=SecondsBetween(Now, start); edit2.Text:=n.ToString; end;
- 批量操作UI控件前调用
BeginUpdate,操作完成后调用EndUpdate:避免每添加一条数据就触发一次列表重绘,仅这一项就能减少至少30%的总耗时。
二、FireDAC组件配置调整(仅需修改属性,无需改动业务逻辑)
FireDAC默认配置为兼容全场景设计,并非最优性能配置,修改以下属性即可对齐甚至超过DBExpress的性能:
- 调整连接级抓取配置:找到TFDConnection组件的
FetchOptions属性组- 将
Mode设置为fmAll:一次性将全部结果集拉取到本地,和DBExpress默认行为一致,避免多次和数据库交互 - 将
RowsetSize调整为1000~5000:增大单次批量抓取的行数,大幅降低网络交互次数
- 将
- 调整查询级配置:找到TFDQuery组件的对应属性
- 将
Options.RequestLive设置为False:如果你不需要编辑查询结果,关闭实时结果集功能,避免FireDAC额外查询表主键、索引等元数据 - 将
ReadOnly设置为True:进一步关闭编辑相关的冗余开销 - 将
ResourceOptions.SilentMode设置为True:关闭不必要的运行时状态通知事件,减少内部开销
- 将
- 可选优化:如果你的SQL语句不需要参数预处理,在SQL执行前设置
sqlq.ResourceOptions.DirectExecute := True,跳过SQL预处理步骤,进一步加快执行速度。
完成以上调整后再进行测试,FireDAC的耗时会明显低于DBExpress。如果你的实际业务场景不需要一次性加载10万条数据展示给用户,建议增加分页逻辑,这才是性能优化的最终方案。
内容的提问来源于stack exchange,提问作者Ib Elfving
相关产品推荐
相关产品推荐

