将1500列项目自身相乘的最佳方法是什么?

时间:2017-11-20 00:07:32

标签: php postgresql laravel postgis

目前我正在使用Laravel和Postgres(扩展名为Postgis)。

我想生成1500个不同位置的路线。

所以1500乘以1500是2.250.000(这是我想要创建的路线数减去相同的位置)。

所以我的问题是:

1)最好的方法是什么? (我的意思是创建2.250.000会给服务器带来压力)

2)我可以做些什么来添加新位置。(因为我需要使用旧添加的位置更新该对)。

3)删除名称相同的对(如柏林和柏林)

2 个答案:

答案 0 :(得分:0)

这是路由之间的自联接,如果您想要天真地进行并创建整个结果集。最好的方法取决于你想对结果做些什么。

听起来你想要每公里充电和降旗费用取决于具体的出发地和目的地。您是否可以将(原产地,目的地)旗帜价格分离为原产地和目的地的固定装货量,以便您只将装货量与每个地点相关联?然后,您无需查询整个表格跨产品来计算价格。

如果无法以这种方式分离出加载模式,那么这些标记价格将如何加载到您的产品交叉产品矩阵中?这部分定价必须已有数据源。

如果您确实要生成交叉产品,删除重复项以及路径对(如(X到Y),(Y到X)),您希望在位置之间使用一些“严格小于”的排序比较,这将自然地消除反向路线和自我路线。或者您可以使用不等式测试来删除自路由并保留反向路由。在以下内容中有适当的encUTF8子句示例:
https://en.wikipedia.org/wiki/Join_(SQL)#Self-join

答案 1 :(得分:0)

Without knowing exactly what you want to insert, hopefully this approach will work for you:

public function insert_locations($locations, $new_locations) {

    // make them into collection if not already
    $locations_coll = Collection::make($locations);

    // chunk the database insert if there are too many records in the collection
    $locations_coll->chunk(500)->each(function($chunk1) {

        $inserts = '';
        // loop through locations
        foreach($chunk1 as $location1) {

            foreach($new_locations as $location2) {

                // if locations are the same then skip
                if($location1==$location2) continue;

                // add to bulk inserts
                $inserts .= '(' . $location1 . '-' . $location2 . '), ' . PHP_EOL;
            }

        }

        // do the bulk insert
        try {
            DB::insert("INSERT INTO your_table (`locations`) VALUES $inserts");
        } catch (Exception $e) {
            print_r([$e->getMessage()]);
        }
    });
}

// get your existing locations
$locations = ['Berlin', 'Hamburg', 'Stuttgart', 'Hannover', 'Heidelberg', 'Bern' ...];

// and get your new locations
$new_locations = ['Berlin', 'Hamburg', 'Stuttgart', 'Hannover', 'Heidelberg', 'Bern' ...];

// call the method
insert_locations($locations, $new_locations);

// get more new locations
$new_locations = ['Bayern'];

// call the method again
insert_locations($locations, $new_locations);

If you want to avoid inserting duplicates you could use something like this in your sql statement:

DB::insert("INSERT INTO your_table (`locations`) VALUES $inserts ON DUPLICATE KEY UPDATE `locations`=VALUES(`locations`)");
相关问题