我正在为房地产门户开发一个PHP应用程序,我有一个带有Properties表的MySQL数据库。此表包含大约500,000行和大约20列属性功能。假设每个要素都是整数。
功能示例:
我需要实现一个带有多滤镜实时导航面板的网页。这个想法是用户可以选择几个特征等于特定值。 例如:1-2个房间(“1”,“2”),建筑物为196x(“6”),状态为平均,良好或优秀(“3”,“4”,“5”),特别是市。
关键要求是用户能够查看每个要素过滤器附近的匹配属性数量,同时考虑当前选定的过滤器。
这是一个示例:
Rooms: 1[X], 2[X], 3[ ] (15000 more), 4[ ] (10000 more)
State: bad[ ] (1000 more), average[X], excellent[X]
Year: 1950[ ] (19000), 1960[ ] (20000), 1970[ ] (18000)
City: A[ ] (25000), B[ ] (18000), C[ ] (30000)
Price: <100000[ ] (20000), >100000[ ] (30000)
“[]”表示空复选框(即未选择过滤值),“[X]”表示选中复选框(即选择过滤值)。
当用户选择特定的特征值时,假设City = London,数字应该会改变,因为它们现在受到先前选择的限制:
Rooms: 1[X], 2[X], 3[ ] (5000 more), 4[ ] (5000 more)
State: bad (1000 more), average[X], excellent[X]
Year: 1950 (19000), 1960 (20000), 1970 (18000)
City: A[X], B (+4000), C (+3000)
Price: <100000 (5000), >100000 (6000)
我尝试对每个功能(X)使用以下SQL查询:
SELECT FeatureX, COUNT(*) AS num FROM properties WHERE selectedFeature1=Val1 AND selectedFeature2=Val2 ... AND selectedFeatureN=ValN GROUP BY featureX;
然而,一组这些查询需要几秒钟,我需要它在实时工作,即在后端<200毫秒。
我试图将整个表保留在共享内存中,但是具有500,000条记录的数组的unserialize()也需要大约1秒。
我找到的唯一解决方案是开发一个独立的应用程序(例如在NodeJS中),它将数据作为对象数组保存在内存中,并为主PHP应用程序提供API。这个应用程序每分钟刷新一次MySQL数据库中的数据。
然而,在开始实现这个之前,我想问一下基于MYSQL本身的任何解决方案是否适用于此类任务?
如果没有,是否有纯粹的PHP解决方案?
您是否有任何通用建议如何处理此类任务?
答案 0 :(得分:0)
并非一切都可以在数据库中解决。
你必须查看所有500K行。任何索引都不太可能帮助超过一小部分可能的查询。所以...我建议你将整个数据保存在RAM中并进行一些快速处理(例如C ++)来运行所有数据。
数据应该是(在MySQL术语中)TINYINT UNSIGNED
,如char unsigned
。可能数据可以存储在20个字节中,每个功能一个字节?这只有10MB的C ++,30-100MB的MySQL,400MB的PHP。 MySQL可以将数据存储在BINARY(20)
中以简化获取,但代价是插入/更新。
使用MySQL作为“事实来源”,定期将其加载到您的处理引擎中(您建议1分钟和Node.js)。然后专注于优化计数。
现在大多数语言都是“解释性的”,因此会产生一定的开销。 C或C ++是在“机器”级别运行的为数不多的两个。我很确定他们可以在200毫秒内完成10M的计算;我怀疑是否有任何解释性语言。