【发布时间】:2018-01-31 21:43:52
【问题描述】:
我有一张名为house 的表。
house 表有 32 列(id、name、floors、doors、color、windows 等)。所以基本上是一个包含不同数据类型(varchar、int、decimal、enum 等)的不同列的表。
现在假设表有 500,000 行。
现在我有了我的用户。他们可以创建一个“房屋搜索”,在其中选择所有 32 列搜索什么。
“房屋搜索”也存储在另一个表 house_search 中。我基本上用所有选定的值做一个简单的INESRT INTO。
在执行此操作时,我想检查表 house 是否有任何“匹配”。
如果我有匹配项,我想将此匹配项插入另一个表 house_match。
问题是我想为搜索打分,所以我不能简单地创建我的 SELECT 来查找正确的行。
长话短说:将给定的“房屋搜索”与所有 500,000 行进行比较的最佳方法是什么?
现在我将“搜索”详细信息存储在 MYSQLI_ASSOC 数组中,然后选择所有房屋并遍历每一行并调用一个进行比较的函数。
问题:非常慢!
// Get the house search data
$sql = "SELECT columnsWeNeedForTheComparison
FROM house_search
WHERE id = ". $_POST['housesearchid'] .";";
$result = $mySQLi->query($sql);
$searchHouse = $result->fetch_assoc();
$sql = "SELECT everyThingFromHouseTableWeNeed
FROM house INNER JOIN ...
INNER JOIN ...;";
$result = $mySQLi->query($sql);
while($checkHouse = $result->fetch_assoc())
{
// call comparison function
$matchPoints = __checkHouseMatch($searchHouse, $checkHouse);
if($matchPoints > 100)
{
$sql = "INSERT INTO house_match
( ..... );";
$insert = $mySQLi->query($sql);
}
}
在__checkHouseMatch()函数中我做了这样的事情
if($searchHouse['buildyear'] == $checkHouse['buildyear'])
{
$matchPoints += 10;
}
else if($searchHouse['buildyear'] == $checkHouse['buildyear'])
{
$matchPoints += 5;
}
如果匹配点是例如> 100 我将INSERT INTO 转换为house_match
INSERT INTO house_match
( housesearchid, houseid )
VALUES
( ". $houseSearchID .", ". $houseID ." );
最好的方法是什么?
我可以考虑
- 将所有房屋存储在一个数组中?
- Cronjob 在晚上不管花多长时间?
非常感谢任何建议!干杯:-)
【问题讨论】:
-
32 列??我会先改变它的结构..添加 i.E. fk 并创建其他表“房屋详细信息”
-
干杯塔德曼!我也使用准备好的语句。所以上面所有的陈述都准备好了。为了更好地理解,我选择给出正常的陈述!
-
感谢 pbalazek!不明白有什么好处?我只在列中存储简单的值(门=2,颜色=1(这是表颜色的 FK),使用房屋=y 等等
-
不要通过内联代码和添加明显的 SQL 注入错误来“简化”您的代码。它不仅会助长坏习惯,还会让你看起来邋遢,并立即对代码的其余部分产生怀疑。像这样的内联内容对理解的唯一作用就是传达一种理解,即你在玩火。
-
这也促使人们练习他们的评论宏。