首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >是否应该使用C++来模拟sql?

是否应该使用C++来模拟sql?
EN

Stack Overflow用户
提问于 2013-09-16 23:49:55
回答 2查看 193关注 0票数 0

目前有一个执行大量计算的sql函数,我想知道下面的是不是一个很好的替代方法。我正在考虑构建一个C#前端应用程序,它调用sql server并提取数据并将其转储到数据表中。在那里,我将把数据作为列表或向量(来自sqldataadaptor类的行)提供给C++,这将更适合于计算。以下是一些假设。

1.必须在C#中完成,唯一的问题是是否引入C++

2. Sql函数目前对数据执行3或4个select语句,这些数据有其唯一的分组依据(最多10个参数)

-So我是否应该将C#中的数据提供给C++预分组(或者按其排序?)并让C++通过构建某种树映射或字典并迭代表来处理此问题。在C#中执行SQL语句并将所有数据分组是很容易的,但是这使得C++作业有点无用,而且它可能是细粒度的

3.我尝试替换的sql计算的格式如下

代码语言:javascript
复制
  select a = exp(sum(log(x))),
     b = exp(sum(log(x))),
     c = exp(sum(log(y))),
     d = exp(sum(log(z))),
     e = exp(sum(log(u)))
  from data_table
  group by e,f,g,h,k

没有什么太复杂的,非常基础的数学。

-Again,在C#中执行这条语句并只返回分组的元素很容易,但这意味着在C#中已经完成了sum()和log(),而C++则变得无用。但是,如果我的表在每次迭代中有数千甚至数万行,并且每天运行多次,那么C++在数学方面会有任何优势吗(我的直觉告诉我不是)。

4.上面的计算对应于1个“帐户”,将有数百个帐户和data_table将有数千行,如果不是更多的每个帐户,这将运行可能每小时24/7。

C#重写是不可避免的,但是是否真的有理由利用C++来提高速度呢?它主要是为了速度和可能的解耦,以便将来的维护,但总体速度。如果我使用C++,那么什么数据结构最适合处理这些数据并模拟它的一些sql功能呢?我基本上需要group by,然后快速迭代它。还有别的选择吗?C++是不是觉得是被迫的,完全没有必要。谢谢。

EN

回答 2

Stack Overflow用户

发布于 2013-09-17 00:36:20

C++的性能提升不足以保证额外的复杂性,特别是在您甚至还没有解决问题之前。首先使用C#,然后看看您的需求是否已经得到满足。

就像ilent2在评论中所说的那样,你总是可以在c++中进行核心计算,并从C#调用-重用大部分C#代码。

此外,看看你的问题,看起来99%的速度将来自于你如何实现解决方案,而不是你选择的语言。去抓他们吧!

票数 2
EN

Stack Overflow用户

发布于 2013-09-17 00:42:51

如果在C#或C++中执行这种计算有任何好处,我会感到非常惊讶。将数据从SQL server传输到C#或C++程序所需的时间将远远超过速度差异。请记住,SQL server仍然使用C++或C#代码将使用的相同的C或C++库(或至少一个非常类似的库),因此实际的explog计算本身在速度上将非常相似。开销来自SQL元素的解析。我不相信会有太大的不同。

如果你真的认为这是一个问题(我不认为,但我不负责你正在做的工作…),我建议你尝试构建一个测试用例,使用一些具有实际值和实际大小的表,然后比较计算值的速度和直接获取值的速度(在纯SQL代码中-我假设有一个SQL命令行工具可以使用,或者一些web界面或允许您执行计算的东西)。也可能只返回值的sum

编辑:我写了一些PHP (因为我的机器上已经安装了PHP + MySQL环境)。不,这些不是我的用户名/密码组合-我不会把它发布在公共服务器上的!

代码语言:javascript
复制
<?php

$dbconnect = mysql_connect("localhost", "username", "password");
if (!$dbconnect)
{
    die('Could not connect: ' . mysql_error());
}
mysql_select_db("test", $dbconnect) 
    or die ("Couldn't connect to database: " . mysql_error() );

echo "Argv[1]=" . $argv[1] . "\n";


if ($argv[1] == "Create")
{
    $rm = getrandmax();
    for($i = 0; $i < 100000; $i++)
    {
        $a = rand() / $rm;
        $b = rand() / $rm;
        $c = rand() / $rm;
        $d = rand() / $rm;
        $e = rand() / $rm;
        $f = rand() / $rm;
        $sql = "INSERT INTO test1 (id, a, b, c, d, e, f) VALUES (" 
            . $i . 
            ", " .  $a . ", " . $b . ", " . $c . ", " . $d . ", " . $e
            . ", " . $f . ");";
        if (mysql_query($sql, $dbconnect) === false)
        {
            die("Could not add element " . mysql_error());
        }
    }
}

if ($argv[1] == "ExpSumLog")
{
    $sql = "SELECT exp(sum(log(a))) AS a1,
                 exp(sum(log(b))) AS b1,
                 exp(sum(log(c))) AS c1,
                 exp(sum(log(d))) AS d1,
                 exp(sum(log(e))) AS e1
          FROM test1
          GROUP BY e,f,id";
    $result = mysql_query($sql, $dbconnect) or die("Failed " . mysql_error());
    $count = 0;
    $sum = 0;
    while($row = mysql_fetch_assoc($result))
    {
        $count++;
        $sum += $row['a1'];
    }

    echo "Sum=" . $sum . ", count=" . $count . "\n";
}


if ($argv[1] == "Sum")
{
    $sum = 0;
    $sql = "SELECT sum(a) AS a1,
                 sum(b) AS b1,
                 sum(c) AS c1,
                 sum(d) AS d1,
                 sum(e) AS e1
          FROM test1
          GROUP BY e,f,id";
    $result = mysql_query($sql, $dbconnect) or die("Failed " . mysql_error());
    $count = 0;
    while($row = mysql_fetch_assoc($result))
    {
        $count++;
        $sum += $row['a1'];
    }

    echo "Sum=" . $sum . ", count=" . $count . "\n";
}

if ($argv[1] == "List")
{
    $sum = 0;
    $sql = "SELECT * FROM test1;";
    $result = mysql_query($sql, $dbconnect) or die("Failed " . mysql_error());
    $count = 0;
    while($row = mysql_fetch_assoc($result))
    {
        $count++;
        $sum += $row['a'];
    }

    echo "Sum=" . $sum . ", count=" . $count . "\n";
}

if ($argv[1] == "SumA")
{
    $sum = 0;
    $sql = "SELECT sum(a) FROM test1;";
    $result = mysql_query($sql, $dbconnect) or die("Failed " . mysql_error());
    $count = 0;
    while($row = mysql_fetch_assoc($result))
    {
        $count++;
        $sum += $row['sum(a)'];
    }

    echo "Sum=" . $sum . ", count=" . $count . "\n";
}

if ($argv[1] == "ExpSumLogA")
{
    $sum = 0;
    $sql = "SELECT sum(exp(log(a))) AS a1 FROM test1;";
    $result = mysql_query($sql, $dbconnect) or die("Failed " . mysql_error());
    $count = 0;
    while($row = mysql_fetch_assoc($result))
    {
        $count++;
        $sum += $row['a1'];
    }
    echo "Sum=" . $sum . ", count=" . $count . "\n";
}   
?>

创建大约需要55分钟...幸运的是,其他步骤要快得多。

代码语言:javascript
复制
Argv[1]=ExpSumLog
Sum=50017.011061374, count=100000

real    0m1.102s
user    0m0.289s
sys 0m0.066s
Argv[1]=Sum
Sum=50017.011061374, count=100000

real    0m1.004s
user    0m0.278s
sys 0m0.055s
Argv[1]=List
Sum=50017.011061374, count=100000

real    0m0.993s
user    0m0.322s
sys 0m0.060s
Argv[1]=SumA
Sum=50017.011061374, count=1

real    0m0.068s
user    0m0.019s
sys 0m0.012s
Argv[1]=ExpSumLogA
Sum=50017.011061374, count=1

real    0m0.095s
user    0m0.024s
sys 0m0.017s

如您所见,执行实际计算所需的时间比复制所有数据所需的时间要短得多。将数据计算为sum(exp(log(A)和sum(a)之间的差异略有不同(但始终不同-对于ExpSumLogA和SumA,每次运行都要慢大约20-30毫秒)。

为了证明数据传输是重点,我添加了以下四种变体:

代码语言:javascript
复制
if ($argv[1] == "SortedA")
{

    $sum = 0;
    $sql = "SELECT a AS a1 FROM test1 ORDER BY a;";
    $result = mysql_query($sql, $dbconnect) or die("Failed " . mysql_error());
    $count = 0;
    while($row = mysql_fetch_assoc($result))
    {
        $count++;
        $sum += $row['a1'];
    }
    echo "Sum=" . $sum . ", count=" . $count . "\n";
}

if ($argv[1] == "SortedExpLogA")
{

    $sum = 0;
    $sql = "SELECT exp(log(a)) AS a1 FROM test1 ORDER BY a;";
    $result = mysql_query($sql, $dbconnect) or die("Failed " . mysql_error());
    $count = 0;
    while($row = mysql_fetch_assoc($result))
    {
        $count++;
        $sum += $row['a1'];
    }
    echo "Sum=" . $sum . ", count=" . $count . "\n";
}

if ($argv[1] == "UnsortedA")
{

    $sum = 0;
    $sql = "SELECT a AS a1 FROM test1;";
    $result = mysql_query($sql, $dbconnect) or die("Failed " . mysql_error());
    $count = 0;
    while($row = mysql_fetch_assoc($result))
    {
        $count++;
        $sum += $row['a1'];
    }
    echo "Sum=" . $sum . ", count=" . $count . "\n";
}

if ($argv[1] == "UnsortedExpLogA")
{

    $sum = 0;
    $sql = "SELECT exp(log(a)) AS a1 FROM test1;";
    $result = mysql_query($sql, $dbconnect) or die("Failed " . mysql_error());
    $count = 0;
    while($row = mysql_fetch_assoc($result))
    {
        $count++;
        $sum += $row['a1'];
    }
    echo "Sum=" . $sum . ", count=" . $count . "\n";
}

显然,这些变体的运行速度比导出所有数据要快,但比“只返回一个值”要慢,它确实是这样做的。

代码语言:javascript
复制
Argv[1]=SortedA
Sum=50017.011061375, count=100000

real    0m0.375s
user    0m0.194s
sys 0m0.027s
Argv[1]=SortedExpLogA
Sum=50017.011061375, count=100000

real    0m0.394s
user    0m0.202s
sys 0m0.023s

Argv[1]=UnsortedA
Sum=50017.011061374, count=100000

real    0m0.353s
user    0m0.206s
sys 0m0.018s
Argv[1]=UnsortedExpLogA
Sum=50017.011061374, count=100000

real    0m0.383s
user    0m0.223s
sys 0m0.025s

正如您所看到的,排序的时间比未排序的要长一点(预计,如果您必须对100K项进行排序,它将增加一些时间),并且ExpLog变体比"just return A“变体稍微慢一些。它是相当一致的,就像这样。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/18832218

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档