2012-07-05 50 views
2

我遇到了一个烦人的问题。内存不足MySQL与24GB服务器

我已经做了系统,现在的用户告诉我,这是给他们的信息:

超出内存(所需268435427个字节)

整个数据库的大小是12MB和查询有问题已经运行好几个月,并不是那么复杂或很大。

该数据库是innodb。我的服务器有24GB的内存,所以我严重怀疑它实际上是内存不足。

的my.cnf如下:

的key_buffer = 8000M

max_allowed_pa​​cket的= 1M

的table_cache = 2048M

sort_buffer_size的值= 1M

的net_buffer_length = 1024M

read_buffer_size = 1M

read_rnd_buffer_size = 24M

innodb_log_file_size = 5M

innodb_log_buffer_size = 8M

的innodb_flush_log_at_trx_commit = 1

innodb_lock_wait_timeout = 50

innodb_buffer_pool_size = 1024M

innodb_additional_mem_pool_size = 2M

MAX_CONNECTIONS = 100

query_cache_size变量= 128M

query_cache_min_res_unit变量= 1024

query_cache_limit = 16MB

thread_cache_size的= 100

max_heap_table_size = 4096MB

在Windows任务管理器中查看时,我看到18.8GB可用,但只有100MB空闲。这是Windows 2008 64位服务器,这可能是问题的根源吗?


下面是该查询:

$currency  = '(SELECT currencies.symbol 
          FROM parts_trading, currencies 
          WHERE parts_trading.enquiryRef = enquiries.id 
          AND parts_trading.sellingCurrency = currencies.id 
          LIMIT 1 
         )' ; 

$amountDueSQL = '(
         (SELECT SUM(quantity*(parts_trading.sellingNet 
            + 
            parts_trading.sellingVat)) 
          FROM parts_trading 
          WHERE parts_trading.enquiryRef = enquiries.id 
         ) 
         + 
         (SELECT SUM(enquiries_custom_fees.feeAmountNet 
            + 
            enquiries_custom_fees.feeAmountVat) 
          FROM enquiries_custom_fees 
          WHERE enquiries_custom_fees.enquiryRef = enquiries.id 
         ) 
         )' ; 
$amountPaidSQL = 'COALESCE(
          (SELECT SUM(jobs_payments_advance.amount) 
           FROM jobs_payments_advance 
           WHERE jobs_payments_advance.jobRef = jobs.id 
          ), 
          0 
         )' ; 

    $result = $dbh->prepare("SELECT SQL_CALC_FOUND_ROWS jobs.id, jobs_states.state, jobs.creationDate, users.username, 
          entity_details.name, enquiries.id as enquiryId, pendingCancelation, 
          IF(entity_details.paymentTermsRef = 1, # Outer IF condition 
           IF($amountDueSQL-$amountPaidSQL = 0.00, # Inner IF condition 
            CONCAT('Paid in full (', $currency, $amountDueSQL, ')') # Inner IF TRUE 
           , # End of inner IF TRUE 
            IF($amountPaidSQL > 0, 
            CONCAT('Part paid (', $currency, $amountPaidSQL, ')'), 
            'Unpaid' 
           ) 
           ) # End of inner IF 

          , # End of TRUE for outer IF 
           (SELECT entity_payment_terms.term 
            FROM entity_details, entity_payment_terms 
            WHERE entity_details.paymentTermsRef 
              = 
              entity_payment_terms.id 
            AND entity_details.id = enquiries.entityRef 
           ) # End of FALSE for outer IF 
          ) AS payState, enquiries.orderNumber, 

          IF((SELECT COUNT(*) 
            FROM invoices_out, (SELECT * FROM invoices_out_reference GROUP BY jobRef) AS tb1 
          WHERE invoices_out.id = tb1.invoiceRef 
          AND tb1.jobRef = jobs.id) > 1, 
           'Part-invoiced', 
           (SELECT invoices_out.date 
            FROM invoices_out, (SELECT * FROM invoices_out_reference GROUP BY jobRef) AS tb1 
          WHERE invoices_out.id = tb1.invoiceRef 
          AND tb1.jobRef = jobs.id) 
          ) AS invoicedDate, 

          enquiries.id AS enquiryId, 

          IF((SELECT COUNT(*) 
            FROM invoices_out, (SELECT * FROM invoices_out_reference GROUP BY jobRef) AS tb1 
          WHERE invoices_out.id = tb1.invoiceRef 
          AND tb1.jobRef = jobs.id) > 1, 
           'Multiple invoices', 
           (SELECT invoices_out.id 
            FROM invoices_out, (SELECT * FROM invoices_out_reference GROUP BY jobRef) AS tb1 
          WHERE invoices_out.id = tb1.invoiceRef 
          AND tb1.jobRef = jobs.id) 
          ) AS invoiceNumber, 

          # If the state is 0 (i.e. they have an account, if true find out their payment terms, if false, instead reference the payment state directly. 
          (SELECT MAX(etaDate) FROM parts_trading WHERE parts_trading.enquiryRef = enquiries.id) AS maxEtaDate, 
          (SELECT COUNT(DISTINCT DATE(etaDate)) FROM parts_trading WHERE parts_trading.enquiryRef = enquiries.id) AS etaCounts, entity_credit_limits.creditLimit AS cLimit, 
          COALESCE((SELECT 
            SUM(qty*parts_trading_buying.buyingNet 
            /
            (SELECT rateVsPound FROM currencies WHERE currencies.id = parts_trading_buying.buyingCurrency)) 
            FROM parts_trading_buying 
            WHERE parts_trading_buying.enquiryRef = enquiries.id 
            ), 0 
            ) AS nonInvoicedBuyingCosts, 
          COALESCE((SELECT 
            SUM(feeAmountNet/(SELECT rateVsPound FROM currencies WHERE currencies.id = parts_trading_buying.buyingCurrency)) 
            FROM parts_trading_buying_charges, parts_trading_buying 
            WHERE parts_trading_buying_charges.partRef = parts_trading_buying.id 
            AND parts_trading_buying.enquiryRef = enquiries.id 
            ), 0 
           ) AS nonInvoicedBuyingFeeCosts, 
          (SELECT 
           SUM(quantity*parts_trading.sellingNet) 
            /
            COALESCE(
             (SELECT invoices_out.rate 
             FROM invoices_out, invoices_out_reference 
             WHERE invoices_out.id = invoices_out_reference.invoiceRef 
             AND invoices_out_reference.jobRef = jobs.id 
             LIMIT 1), 
             (SELECT rateVsPound 
             FROM currencies 
             WHERE currencies.id = parts_trading.sellingCurrency) 
            ) 
          FROM parts_trading 
          WHERE parts_trading.enquiryRef = enquiries.id 
          ) AS sellingParts, 
          COALESCE((SELECT 
            SUM(enquiries_custom_fees.feeAmountNet) 
            /
            COALESCE(
             (SELECT rate 
             FROM invoices_out, invoices_out_reference 
             WHERE invoices_out.id = invoices_out_reference.invoiceRef 
             AND invoices_out_reference.jobRef = jobs.id LIMIT 1), 
             (SELECT rateVsPound 
             FROM currencies 
             WHERE currencies.id = parts_trading.sellingCurrency 
             ) 
            ) 
            FROM enquiries_custom_fees, parts_trading 
            WHERE enquiries_custom_fees.enquiryRef = enquiries.id 
            AND parts_trading.enquiryRef = enquiries.id), 0) AS sellingFees, 
          COALESCE((SELECT 
            SUM(parts_shipping_out.shippingOutCost) 
            FROM parts_shipping_out, parts_shipping_arrival_dates, parts_shipping_v2 
            WHERE parts_shipping_out.arrivalsRef = parts_shipping_arrival_dates.id 
            AND parts_shipping_arrival_dates.shippingRef = parts_shipping_v2.id 
            AND parts_shipping_v2.jobRef = jobs.id 
            ), 0 
           ) AS actualShippingOutFromEua, 
          (SELECT 

           SUM(quantity*parts_trading.sellingNet) 
            /
            COALESCE(
             (SELECT invoices_out.rate 
             FROM invoices_out, invoices_out_reference 
             WHERE invoices_out.id = invoices_out_reference.invoiceRef 
             AND invoices_out_reference.jobRef = jobs.id 
             LIMIT 1), 
             (SELECT rateVsPound 
             FROM currencies 
             WHERE currencies.id = parts_trading.sellingCurrency) 
            ) 
           + 
           COALESCE((SELECT 
            SUM(enquiries_custom_fees.feeAmountNet) 
            /
            COALESCE(
             (SELECT rate 
             FROM invoices_out, invoices_out_reference 
             WHERE invoices_out.id = invoices_out_reference.invoiceRef 
             AND invoices_out_reference.jobRef = jobs.id LIMIT 1), 
             (SELECT rateVsPound 
             FROM currencies 
             WHERE currencies.id = parts_trading.sellingCurrency 
             ) 
            ) 
            FROM enquiries_custom_fees 
            WHERE enquiries_custom_fees.enquiryRef = enquiries.id), 0) 
           - 
           COALESCE((SELECT 
            SUM(qty*parts_trading_buying.buyingNet 
            /
            (SELECT rateVsPound FROM currencies WHERE currencies.id = parts_trading_buying.buyingCurrency)) 
            FROM parts_trading_buying 
            WHERE parts_trading_buying.enquiryRef = enquiries.id 
            ), 0 
            ) 
           - 
           COALESCE((SELECT 
            SUM(feeAmountNet/(SELECT rateVsPound FROM currencies WHERE currencies.id = parts_trading_buying.buyingCurrency)) 
            FROM parts_trading_buying_charges, parts_trading_buying 
            WHERE parts_trading_buying_charges.partRef = parts_trading_buying.id 
            AND parts_trading_buying.enquiryRef = enquiries.id 
            ), 0 
           ) 
           - 
           COALESCE((SELECT 
            SUM(parts_shipping_out.shippingOutCost) 
            FROM parts_shipping_out, parts_shipping_arrival_dates, parts_shipping_v2 
            WHERE parts_shipping_out.arrivalsRef = parts_shipping_arrival_dates.id 
            AND parts_shipping_arrival_dates.shippingRef = parts_shipping_v2.id 
            AND parts_shipping_v2.jobRef = jobs.id 
            ), 0 
           ) 
           FROM parts_trading, parts_trading_buying 
           WHERE parts_trading.enquiryRef = enquiries.id 
           AND parts_trading_buying.counterpartRef = parts_trading.id 
          ) AS margin 
          FROM jobs, 
          jobs_states, enquiries, users, jobs_payment_status, entity_details 
          LEFT JOIN entity_credit_limits ON entity_details.id = entity_credit_limits.entityRef 
          WHERE jobs.stateRef = jobs_states.id 
          AND IF(paymentStateRef = 0, 1, (jobs_payment_status.id = jobs.paymentStateRef)) 
          #^If true it causes a result for each payment state (i.e. 3), so we group on state below, shouldn't cause probs. 
          AND jobs.enquiryRef = enquiries.id 
          AND enquiries.entityRef = entity_details.id 
          AND users.id = enquiries.traderRef 
          AND enquiries.traderRef = ? 
           LIMIT ?, ?") ; 

如果我尝试设置上面3.5GB的Apache PHP执行内存无法启动(我使用的XAMPP)。我必须使用32位版本的PHP?这对于INNODB_BUFFER_POOL_SIZE来说是相同的,我希望它是14GB,但是如果我这样做的话mysql将不会启动。

+0

什么是查询?你还可以提供相关的表格+索引... – BugFinder

+0

索引占用大量空间,如果你在很多列上定义了索引,可能会导致问题 –

回答

1

我不认为这是一个数据库相关的问题,因为这种错误(内存不足(需要268435427字节))大部分时间由PHP(无限循环或类似的东西可能是问题)抛出。

+0

即使我在PHPMyAdmin中单独运行查询?我仍然得到错误。 – imperium2335

+0

试着用mysql直接运行它。也许PHP的执行内存限制很低。 –

0

现在(两分钟的时间),您可以使用MySQLCalculator.com查看基本的RAM占用空间。 如果配置中的每个连接RAM条目都有一个前导#,那么您将运行良好,实际上要好得多。使用read_rnd_buffer_size = 24M的行而不是默认的256K,您正在读取96倍以上的索引信息。