每秒插入 3333 行。一定要以某种方式“批量”插入。如需更高的插入率,请参阅http://mysql.rjweb.org/doc.php/staging_table
DOUBLE
对于 lat/lng 来说太过分了,而且浪费空间。表的大小可能会导致性能问题(当表变得“巨大”时)。对于定位车辆,FLOAT
可能更好——2 个浮点数为 8 个字节,而 2 个双精度数为 16 个字节。分辨率为 1.7 m (5.6 ft)。参考:http:
//mysql.rjweb.org/doc.php/latlng#representation_choices
另一方面,如果每个用户只有一个 lat/lng,一百万行将小于 100MB,而不是一个很大的表。
要执行哪些查询?针对一个表的一百万行可能会很昂贵。“查找 10 英里(或公里)内的所有用户”需要进行表扫描。建议查看边界框,以及几个二级索引。
更多的
更新位置的调用应该连接、更新、断开连接。这将花费几分之一秒,并且可能不会超载max_connections
。该设置不应太高;它可能会招来麻烦。也设置back_log
为大致相同的值。
考虑“连接池”,其细节取决于您的应用程序语言、Web 服务器、MySQL 版本等。
连同中的“边界框” WHERE
,有INDEX(lat), INDEX(lng)
;优化器将在它们之间进行选择。
现在您的服务器中有许多 CPU 内核?将网络服务器线程的数量限制为大约两倍。这提供了另一种节流机制来避免“雷击群综合症”。
query_cache_size=0
通过同时使用和来关闭查询缓存query_cache_type=0
。否则,QC 会花费一些开销,而基本上不会提供任何好处。
批处理INSERTs
是可行的。但是你需要批处理UPDATEs
。这更棘手。通过在表中收集更新,然后执行单个多表,UPDATE
从该表复制到主表中应该是实用的。这个额外的表格可以像我在“staging_table”链接中讨论的乒乓球一样工作。但是...首先让我们看看其他修复是否足够。
使用innodb_flush_log_at_trx_commit = 2
. 否则,瓶颈将是记录事务。缺点(丢失 1 秒的更新)可能对您的应用程序来说不是问题——因为您很快就会获得另一个 lat/lng。
寻找附近的车辆——这甚至比边界框更好,但更复杂:http: //mysql.rjweb.org/doc.php/latlng。多久寻找“附近”。我希望不是 3333/秒;这在单个服务器中是不切实际的。(多个从站可以提供一个解决方案。)无论如何,结果集不会很快改变。