복붙노트

[SQL] 응용 프로그램에서 SQL 대에서 계산을 수행의 장점과 단점은 무엇입니까

SQL

응용 프로그램에서 SQL 대에서 계산을 수행의 장점과 단점은 무엇입니까

가게 주인 테이블은 다음과 같은 필드가 있습니다 :

id (bigint),amount (numeric(19,2)),createddate (timestamp)

하자 말, 나는 위의 표가 있습니다. 어제의 기록을 얻을 싶어 센트 프린트 량이하여 보고서를 생성.

일을하는 한 가지 방법은 내 자바 응용 프로그램에서 계산을 수행하고 간단한 쿼리를 실행하는 것입니다

Date previousDate ;// $1 calculate in application

Date todayDate;// $2 calculate in application

select amount where createddate between $1 and $2 

다음 내 자바 응용 프로그램에서 센트의 기록과 변환의 양을 반복하고 보고서를 생성

또 다른 방법은 SQL 쿼리 자체에서 계산을 수행 같다 :

select cast(amount * 100 as int) as "Cents"
from shopkeeper  where createddate  between date_trunc('day', now()) - interval '1 day'  and  date_trunc('day', now())

다음 기록을 반복하고 보고서를 생성

하나의 방법으로, 내 모든 처리는 자바 응용 프로그램에서 수행되며, 간단한 쿼리가 발생합니다. 다른 경우에는 모든 변환과 계산은 SQL 쿼리에서 이루어집니다.

위의 사용 사례는 실제 시나리오에서 테이블은 유사한 종류의 처리를 필요로하는 많은 열을 가질 수 있습니다, 단지 예입니다.

당신은 성능과 다른 측면 및 이유의 측면에서 더 나은하는 방법 말해 주시겠습니까?

해결법

  1. ==============================

    1.대부분의 결정적하지만 - 그것은 많은 요인에 따라 달라집니다

    대부분의 결정적하지만 - 그것은 많은 요인에 따라 달라집니다

    당신은 행과 열, 응용 프로그램 서버에 데이터를 다시 가져 최소화 할 경우 언제나처럼, 당신의 이점에있을 것입니다. 확인한 다음 쿼리를 튜닝하고 적절하게 두 시나리오 도움이 될 것입니다 색인.

    메모를 다시 :

    집합 기반 작업을 선호 기록 - 기록을 반복하는 것은 거의 항상 SQL에서 할 수있는 잘못된 일이다.

    그러나, 항상 서버에서 우아한 쿼리가 대역폭을 많이 절약 할 수 있습니다 시나리오 예제가 있습니다 - 일반적으로, 나는 "이 데이터를 가져,이 데이터를 저장하는"최소 데이터베이스의 작업을 유지하는 것을 선호합니다.

    또한 고려 :이 계산 비용이 높은 경우, 그것은 어딘가를 캐시 할 수 있습니까?

    당신은 "더 나은이다"정확한 싶은 경우에; 코드 그 두 가지와는 (하나의 초안이 조정 된 100 %가 가능성이 높다고 지적)를 비교합니다. 그러나 일반적인 사용에서와 요인 : "그 중 1 대 이들의 1"단지 하나의 비교하지 않는다 : 현실에서, 그것은 한 번에 (별도) 5 번 호출되고, 경우 해당 시뮬레이션합니다.

  2. ==============================

    2.나 은유를 사용하자 : 당신이 파리에서 황금 목걸이를 구입하려는 경우 금세 기술과 취향의 문제이다 케이프 타운이나 파리에 앉아 있었다. 그러나 당신은 프랑스에 남아프리카 공화국에서 금 광석의 톤을 제공하지 않을 것입니다. 광석은 광산 현장에서 처리되는 (또는 일반 영역에서 적어도)에만 금 배송 얻는다. 같은 앱 및 데이터베이스에 대한 진실해야한다.

    나 은유를 사용하자 : 당신이 파리에서 황금 목걸이를 구입하려는 경우 금세 기술과 취향의 문제이다 케이프 타운이나 파리에 앉아 있었다. 그러나 당신은 프랑스에 남아프리카 공화국에서 금 광석의 톤을 제공하지 않을 것입니다. 광석은 광산 현장에서 처리되는 (또는 일반 영역에서 적어도)에만 금 배송 얻는다. 같은 앱 및 데이터베이스에 대한 진실해야한다.

    지금까지의 PostgreSQL에 관한 한, 당신은 아주 효율적으로, 서버에서 거의 모든 작업을 수행 할 수 있습니다. 는 복잡한 쿼리 탁월를 RDBMS. TCL, 파이썬, 펄 및 더 많은 : 절차 적 요구를 들어 서버 측 스크립트 언어의 다양한 선택할 수 있습니다. 대부분 그래도 난, PL / pgSQL의를 사용합니다.

    최악의 시나리오는 반복적으로 더 큰 집합의 모든 단일 행에 대한 서버로 이동하는 것입니다. (즉 광석 1 톤에게 시간을 출하처럼 될 것입니다.)

    당신은 쿼리의 폭포를 보낼 경우 모든 서버에 하나의 조회 또는 프로 시저에서 수행 할 수 있지만 두 번째 줄에, 각각은, 전에 하나에 따라 달라집니다. (즉, 순차적으로, 별도의 배와 보석의 각 금 배송처럼하고).

    응용 프로그램과 서버 사이의 앞뒤를가는 것은 비싸다. 서버와 클라이언트하십시오. 그 줄이려고 시도하고 당신은 이길 것이다 - ERGO : 사용 서버 측 절차 및 / 또는 복잡한 SQL을 필요한 경우.

    우리는 단지 우리가 포스트 그레스의 함수로 거의 모든 복잡한 쿼리를 포장하는 프로젝트를 완료했다. 응용 매개 변수를 넘긴는 필요한 데이터 세트를 가져옵니다. 빠르고 (응용 프로그램 개발자를위한) 깨끗하고 단순, I / O는 최소 ... 낮은 탄소 발자국과 함께 빛나는 목걸이로 감소.

  3. ==============================

    3.데이터베이스 엔진이 자바보다 더 효율적 소수점 연산 루틴을 가질 가능성이 경우에 당신은 약간 더 나은 SQL에서 계산을 해제 아마.

    데이터베이스 엔진이 자바보다 더 효율적 소수점 연산 루틴을 가질 가능성이 경우에 당신은 약간 더 나은 SQL에서 계산을 해제 아마.

    일반적으로하지만 행 레벨 계산에 큰 차이가 없습니다.

    어디 만들 않는 차이가있다 :

  4. ==============================

    4.없어 더 블랙 / 데이터 액세스 로직의 일부가 SQL에서 수행되어야 및 부품 응용 프로그램에서 수행해야하는지 무엇에 대한 흰색. 내가 마크 Gravell의 표현처럼, 구별

    없어 더 블랙 / 데이터 액세스 로직의 일부가 SQL에서 수행되어야 및 부품 응용 프로그램에서 수행해야하는지 무엇에 대한 흰색. 내가 마크 Gravell의 표현처럼, 구별

    SQL의 힘과 표현력이 크게 과소 평가된다. 윈도우 함수의 도입 이후, 비 엄격하게 설정 지향적 인 계산의 많은 데이터베이스에 매우 쉽고 우아하게 수행 할 수 있습니다.

    엄지 손가락의 세 가지 규칙에 관계없이 항상 전체 애플리케이션 아키텍처, 따라야한다 :

    내 경험에 의하면, 괜찮은 DBA하고 괜찮은 데이터베이스에 대한 몇 가지 괜찮은 지식, 당신은 곧 당신의 데시벨의 CPU 제한으로 실행되지 않습니다.

    이러한 일들이 설명되어 일부 추가 읽기 :

  5. ==============================

    5.SQL에서 일반적으로 할 일의 일에서 동일하거나 다른 프로젝트에서 다른 모듈 또는 구성 요소가 그 결과를 얻을해야합니다 가능성이있는 경우. 방금 추가 처리없이 최종 값을 얻을 수있는 DB 관리 도구에서 저장된 프로 시저를 호출 할 필요가 있기 때문에 원자 작동 할 서버 측이 더이기도합니다.

    SQL에서 일반적으로 할 일의 일에서 동일하거나 다른 프로젝트에서 다른 모듈 또는 구성 요소가 그 결과를 얻을해야합니다 가능성이있는 경우. 방금 추가 처리없이 최종 값을 얻을 수있는 DB 관리 도구에서 저장된 프로 시저를 호출 할 필요가 있기 때문에 원자 작동 할 서버 측이 더이기도합니다.

    어떤 경우에는 이것이 적용되지 않습니다하지만 그렇게되면 그것은 의미가 있습니다. 또한 일반적으로 데시벨 상자가 최고의 하드웨어와 성능을 가지고있다.

  6. ==============================

    6.당신이 ORM의 상단이나 캐주얼 낮은 성능의 응용 프로그램을 작성, 사용을 작성하는 경우 어떤 패턴은 응용 프로그램을 단순화합니다. 당신은 고성능 응용 프로그램을 작성 및 규모에 대해 신중하게 생각하는 경우에, 당신은 데이터 처리를 이동하여 이길 것이다. 난 강력하게 데이터에 처리를 이동 옹호.

    당신이 ORM의 상단이나 캐주얼 낮은 성능의 응용 프로그램을 작성, 사용을 작성하는 경우 어떤 패턴은 응용 프로그램을 단순화합니다. 당신은 고성능 응용 프로그램을 작성 및 규모에 대해 신중하게 생각하는 경우에, 당신은 데이터 처리를 이동하여 이길 것이다. 난 강력하게 데이터에 처리를 이동 옹호.

    거래 (1) OLTP (기록의 소수)의 두 단계로 생각해 보자. (2) OLAP (많은 레코드의 긴 스캔).

    (- 초당 100,000 거래 만 -10), 당신은 데이터베이스에서 잠금 및 죽은 잠금 경합을 래치 제거해야 OLTP의 경우, 경우에 당신은 빨리하고 싶다. 당신이 거래에서 긴 노점 제거 할 필요가 있다고이 수단 : 클라이언트로 처리하는 이동 DB 클라이언트에서 왕복은 하나의 긴 스톨입니다. 당신은 긴 (make가 원자 / 업데이트를 읽을 수있는) 트랜잭션을 살았 매우 높은 처리량을 가질 수 없습니다.

    제목 : Re : 수평 확장을. 현대 데이터베이스는 수평으로 확장 할 수 있습니다. 이러한 시스템은 HA를 구현하고 이미 결함 허용. 및 응용 프로그램 공간을 단순화하려고 활용.

    OLAP에서 살펴 보자는 -이 경우에는 아마도 드래그하면 다시 응용 프로그램 데이터 terrabytes 끔찍한 생각이 분명해야한다. 이 시스템은 특히 원주 데이터를 조직 사전, 매우 효율적으로 압축에 대한 작동 내장되어 있습니다. 현대 OLAP 시스템은 수평 확장 및 분산 작업이 수평 (내부적으로 데이터를 처리 이동) 그 정교한 쿼리 계획을 가지고있다.

  7. ==============================

    7.우리는 비즈니스 구현에 목표를 확인할 수있는 경우 프런트 엔드에서 계산을 수행하는 여부 백엔드에서 매우 결정됩니다. 당시 자바 코드는 모두 잘 작성된 SQL 코드보다 더 수행 할 수 있거나 그 반대 일 수 있습니다. 혼동하지만 여전히 먼저 결정하기 위해 시도 할 수 있습니다 -

    우리는 비즈니스 구현에 목표를 확인할 수있는 경우 프런트 엔드에서 계산을 수행하는 여부 백엔드에서 매우 결정됩니다. 당시 자바 코드는 모두 잘 작성된 SQL 코드보다 더 수행 할 수 있거나 그 반대 일 수 있습니다. 혼동하지만 여전히 먼저 결정하기 위해 시도 할 수 있습니다 -

    코드를 배치 할 위치를 결정하기 전에 당신이 생각할 수있는 많은 다른 측면이있다. 한 인식은 완전히 잘못된 것입니다 - 모든 자바 (응용 프로그램 코드) 및 / 베스트 수행 할 수 있습니다 또는 모든 것이 DB (SQL 코드)에 의해 수행하는 것이 가장 좋습니다.

  8. ==============================

    8.성능의 관점을 형성이 거의 확실 실제로 underly 디스크 데이터베이스로부터 데이터를 가져 오는 것보다 훨씬 더 빠르게 수행 될 수있는 매우 간단한 산술 연산이다. 또한, where 절에있는 값을 계산하는 매우 빠르고 어떤 런타임에있을 가능성이 높습니다. 요약하면, 병목 디스크 IO의 값이 아니라 계산되어야한다.

    성능의 관점을 형성이 거의 확실 실제로 underly 디스크 데이터베이스로부터 데이터를 가져 오는 것보다 훨씬 더 빠르게 수행 될 수있는 매우 간단한 산술 연산이다. 또한, where 절에있는 값을 계산하는 매우 빠르고 어떤 런타임에있을 가능성이 높습니다. 요약하면, 병목 디스크 IO의 값이 아니라 계산되어야한다.

    가독성 당, 나는 당신이 ORM을 사용하는 경우 ORM 당신이 세트를 기반으로 작업을 사용하여 매우 쉽게 기본 데이터로 작업 할 수 있기 때문에 당신이 당신의 애플리케이션 서버 환경에서 작업을 수행한다고 생각합니다. 어쨌든 원시 SQL을 작성하려는 경우,이 계산을하고와 아무것도 잘못된 거기, 당신의 SQL은 조금 더 좋은 및 올바른 형식의 경우 읽기 쉽게 보일 것이다.

  9. ==============================

    9.결정적으로, "성능"정의되어 있지 않습니다.

    결정적으로, "성능"정의되어 있지 않습니다.

    하나는 나에게 중요한 것은 대부분의 개발자 시간입니다.

    SQL 쿼리를 작성합니다. 너무 느린 또는 DB는 병목 현상이 경우, 재고. 그때까지, 당신은 두 가지 방법 벤치 마크 할 수 있어야하고, 당신의 결정은 당신의 설정 (하드웨어 및 어떤 스택 당신이있어)와 관련된 실제 데이터를 기반으로 만들 수 있습니다.

  10. ==============================

    10.나는 성능 차이는 특정 사례 및 벤치 마크없이 대해 추론 할 수 있다고 생각하지 않습니다,하지만 난 다른 테이크를 가지고 :

    나는 성능 차이는 특정 사례 및 벤치 마크없이 대해 추론 할 수 있다고 생각하지 않습니다,하지만 난 다른 테이크를 가지고 :

    어떤 당신이 더 유지할 수 있습니다? 예를 들어, 플래시 또는 HTML5, 또는 C ++, 또는 뭔가 다른 자바에서 프런트 엔드를 전환 할 수 있습니다. 프로그램의 광대 한 수는 이러한 변화를 통해 간, 또는 여러 장치에 작업을해야하기 때문에 심지어로 시작하는 두 개 이상의 언어에 존재했다.

    당신은 적절한 중간 계층이 경우에도 해당 레이어가 변경 될 수 있습니다 및 JBoss는 루비 / 레일 될 수도, (주어진 예제를 그런 경우가 아니다처럼 보인다).

    한편,이 점은 논의의 여지가 있도록, SQL과 관계형 DB하지 그리고 당신이 할 경우에도, 당신은 어쨌든 처음부터 프런트 엔드를 다시 작성해야합니다 뭔가와 SQL-백엔드를 대체 할 것 같지는 않다.

    내 생각은 당신이 DB에서 계산을 할 경우, 당신이 모든 것을 다시 구현하지 않기 때문에, 나중에 두 번째 프런트 엔드 또는 중간 계층을 작성하기가 훨씬 더 쉬워 질 것입니다. 실제로 그러나, 나는 "나는 사람들이 이해하는 것을 코드로이 작업을 수행 할 수있는"가장 중요한 요소라고 생각합니다.

  11. ==============================

    11.로드 밸런싱을보고하는 것이 대답하는 방법을 단순화합니다. 당신은 (그것이 어떤 의미가있는 경우) 당신이 가장 용량이 부하를 넣고 싶다. 대부분의 시스템에서 그것은 아마 대답은 당신이 SQL이 더는에이보다 일 1 온스를하고 싶지 않아 그래서 빨리 병목이되는 SQL 서버입니다.

    로드 밸런싱을보고하는 것이 대답하는 방법을 단순화합니다. 당신은 (그것이 어떤 의미가있는 경우) 당신이 가장 용량이 부하를 넣고 싶다. 대부분의 시스템에서 그것은 아마 대답은 당신이 SQL이 더는에이보다 일 1 온스를하고 싶지 않아 그래서 빨리 병목이되는 SQL 서버입니다.

    또한 대부분의 아키텍쳐에서 그것을에 추가됩니다 시스템 및 외부 시스템의 핵심을 구성하는 SQL 서버 (들)입니다.

    그러나 수학은 위의 당신이 한계에 넣을 수있는 가장 좋은 장소 시스템을 밀어하지 않는 당신을 데려 가고 싶다는 곳이 너무 간단하다. 수학은 거리 계산은 다음의 노력이 아닌 사소한 될 수도 말하고 신중한 계획과 테스트를 필요로 죄 / 왜냐하면 / 황갈색 계산으로 사소한 아니었다면.

  12. ==============================

    12.이 질문에 대한 다른 답변은 흥미 롭다. 놀랍게도, 아무도 당신의 질문에 대답하지 않았다. 당신은 궁금 :

    이 질문에 대한 다른 답변은 흥미 롭다. 놀랍게도, 아무도 당신의 질문에 대답하지 않았다. 당신은 궁금 :

    더 많은 정보: 질문 하나를 들어 당신이해야한다는하려는 분수를 집계    반올림 오류없이 작동합니다. 나는 숫자 19,2 합리적인 생각    돈과 두 번째 경우에 정수는 OK입니다. 돈을 위해 float를 사용하는 것은 이러한 이유에 대한 잘못된 것입니다.

    질문이, 나는의 프로그래머로 모든 권한을 가지고 좋아    날짜는 "지금"간주됩니다. 자동 장치를 쓰기 어려울 수 있습니다    사용 기능 이제 원하는 경우 시험 (). 또한, 때 당신은 더 이상이    트랜잭션 스크립트는 변수를 설정 이제 같음 () 그래서 변수를 사용하는 것이 좋을 수 있습니다    논리 모두 동일한 값을 사용.

  13. ==============================

    13.제가이 질문을 해결하기 위해 실제 예를 보자

    제가이 질문을 해결하기 위해 실제 예를 보자

    나는 각 그렇게 할 수있는 기호로, 나는 134000 촛불에 대한이 내 OHLC 데이터에 대한 가중 이동 평균을 계산하는 데 필요한

    어느 쪽이 더 나은 무엇입니까?

    요구 사항

    당신에게 격려를 제공하기 위해, 이것은 가중 이동 평균을 할 수있는 파이썬 버전입니다

    WMA 코드를 통해 수행

    import psycopg2
    import psycopg2.extras
    from talib import func
    import timeit
    import numpy as np
    with psycopg2.connect('dbname=xyz user=xyz') as conn:
    with conn.cursor() as cur:
    t0 = timeit.default_timer()
    cur.execute('select distinct symbol from ohlc_900 order by symbol')
    for symbol in cur.fetchall():
    cur.execute('select c from ohlc_900 where symbol = %s order by ts', symbol)
    ohlc = np.array(cur.fetchall(), dtype = ([('c', 'f8')]))
    wma = func.WMA(ohlc['c'], 10)
    # print(*symbol, wma[-1])
    print(timeit.default_timer() - t0)
    conn.close()
    

    SQL을 통해 WMA

    """
    if the period is 10
    then we need 9 previous candles or 15 x 9 = 135 mins on the interval department
    we also need to start counting at row number - (count in that group - 10)
    For example if AAPL had 134 coins and current row number was 125
    weight at that row will be weight = 125 - (134 - 10) = 1
    10 period WMA calculations
    Row no Weight c
    125 1
    126 2
    127 3
    128 4
    129 5
    130 6
    131 7
    132 8
    133 9
    134 10
    """
    query2 = """
    WITH
    condition(sym, maxts, cnt) as (
    select symbol, max(ts), count(symbol) from ohlc_900 group by symbol
    ),
    cte as (
    select symbol, ts,
    case when cnt >= 10 and ts >= maxts - interval '135 mins'
    then (row_number() over (partition by symbol order by ts) - (cnt - 10)) * c
    else null
    end as weighted_close
    from ohlc_900
    INNER JOIN condition
    ON symbol = sym
    WINDOW
    w as (partition by symbol order by ts rows between 9 preceding and current row)
    )
    select symbol, sum(weighted_close)/55 as wma
    from cte
    WHERE weighted_close is NOT NULL
    GROUP by symbol ORDER BY symbol
    """
    with psycopg2.connect('dbname=xyz user=xyz') as conn:
    with conn.cursor() as cur:
    t0 = timeit.default_timer()
    cur.execute(query2)
    # for i in cur.fetchall():
    # print(*i)
    print(timeit.default_timer() - t0)
    conn.close()
    

    믿거 나 말거나, 쿼리가 빠르게 가중 이동 평균을하는 순수 파이썬 버전보다 실행! 그래서 해당 쿼리를 작성에 단계적으로 가서 거기에 걸 당신은 잘 할 것이다

    속도

    0.42141127300055814 초 파이썬

    0.23801879299935536 초 SQL

    즉 SQL 앱 서버를 능가 할 수있는 곳의 예입니다, 그래서 나는 1000 개 주식 사이에 나누어 내 데이터베이스에서 134,000 가짜 OHLC 레코드가

  14. from https://stackoverflow.com/questions/7510092/what-are-the-pros-and-cons-of-performing-calculations-in-sql-vs-in-your-applica by cc-by-sa and MIT license