差不多all每行函数都会对性能产生影响,唯一真正的问题是:“影响是否小到不用担心?”。
您应该通过测量而不是猜测来发现这一点。如果您的数据和查询都没有改变,那么数据库管理只是一项“一劳永逸”的活动。否则,您应该定期监控性能以确保不会出现问题。
上面评论中的“足够小”,我的意思是,您可能不必担心以下内容对性能的影响:
select * from friends where lowercase(lastname) = "smith"
如果你只有三个朋友。
随着表大小的增加,这些因素的影响变得更加严重。例如,如果您有一亿个客户,并且您想找到所有可能与计算机相关的客户,您就不会想尝试:
select name from customers where lowercase(name) like '%comp%'
这可能会让 DBA 像一堆砖头一样打击你。
我们过去解决此问题的一种方法是在数据中引入冗余。使用第一个示例,我们将添加一个名为的额外列lowerlastname
并用小写值填充它lastname
。然后将其编入索引以用于搜索目的,然后您的select
声明变得快得令人眼花缭乱,这是理所应当的。
我听到你问,这对我们深受喜爱的 3NF 有何影响?答案是“不多”,如果你知道自己在做什么:-)
您可以设置数据库,以便由插入/更新触发器填充此新列,以保持数据一致性。如果您了解并减轻后果,出于性能原因违反 3NF 是完全可以接受的。
同样,第二个查询可以有一个插入/更新触发器来填充新的索引列name_contains_comp
每当更新或插入包含相关文本的条目时。
由于大多数数据库的读取次数远多于写入次数,因此这会将计算成本转移到插入/更新,从而有效地将其分摊到所有选择操作中。那么查询将是:
select name from customers where name_contains_comp = 'Y'
同样,您会发现查询速度快得令人眼花缭乱,但插入和更新速度稍慢。