Набор результатов запроса слишком велик - PullRequest
3 голосов
/ 05 мая 2011

У меня есть запрос, который может быть быстрым или медленным в зависимости от того, сколько записей я получаю. Вот таблица, показывающая число в моем предложении LIMIT и соответствующее время, необходимое для выполнения запроса и получения результатов:

LIMIT | Seconds (Duration/Fetch)
------+-------------------------
   10 |  0.030/  0.0
  100 |  0.062/  0.0
 1000 |  1.700/  0.8
10000 | 25.000/100.0

Как вы можете видеть, это нормально, по крайней мере, до 1000, но 10000 действительно медленно, в основном из-за большого времени выборки. Я не понимаю, почему рост времени выборки не является линейным, но я am собираю более 200 столбцов из более чем 70 таблиц, поэтому тот факт, что для получения набора результатов требуется много времени, не является сюрприз.

Кстати, я получаю данные по всем счетам в определенном банке. В банке, с которым я работаю, около 160 000 счетов, поэтому в конечном итоге мне нужно получить 160 000 строк из базы данных.

Очевидно, что будет невозможно попытаться извлечь 160 000 строк одновременно (по крайней мере, если я не смогу существенно оптимизировать свой запрос). Мне кажется, что самый большой блок, который я могу разумно захватить, - это 1000 строк, поэтому я написал скрипт, который будет выполнять запрос снова и снова с SELECT INTO OUTFILE, лимитом и смещением. Затем в конце я беру все CSV-файлы, которые я сбросил, и cat их вместе. Это работает, но это медленно. Это занимает часы. У меня сейчас запущен скрипт, и за час примерно 43000 строк.

Должен ли я атаковать эту проблему на уровне оптимизации запросов или долгое время выборки предполагает, что мне следует сосредоточиться на другом месте? Что бы вы порекомендовали мне сделать?

Если вы хотите увидеть запрос, вы можете увидеть его здесь .

Ответы [ 3 ]

1 голос
/ 05 мая 2011

Ответ будет сильно зависеть от того, что вы делаете с данными. Запросы 215 столбцов через 29 объединений никогда не будут быстрыми для нетривиальных размеров записей.

Если вы пытаетесь отобразить 160 000 записей для пользователя, вы должны отобразить результаты и получать только одну страницу за раз. Это будет держать набор результатов достаточно маленьким, чтобы даже относительно неэффективный запрос быстро возвращался. В этом случае вы также захотите проверить, сколько данных необходимо пользователю для выбора или манипулирования данными. Скорее всего, вы можете сократить его до нескольких полей и некоторых агрегатов (счет, сумма и т. Д.), Которые позволят пользователю принять обоснованное решение о том, с какими записями он хочет работать. Используйте LIMIT со смещением для извлечения отдельных страниц произвольного размера.

Если вам необходимо экспортировать данные для целей отчетности, убедитесь, что вы извлекаете только те данные, которые необходимы для отчета. По возможности исключайте объединения и используйте подзапросы, где вам нужна совокупность дочерних данных. Вы хотите настроить / добавить индексы для часто используемых объединений и критериев. В случае вашего предоставленного запроса ib.id и множества внешних ключей, через которые вы присоединяетесь. Вы можете не указывать логические столбцы, так как для формирования значимого индекса недостаточно отдельных значений.

Независимо от того, что вы пытаетесь выполнить, удаление некоторых объединений и столбцов по своей сути ускорит вашу обработку. Тяжелая работа, которую MySQL должен выполнить для выполнения этого запроса, - ваш главный камень преткновения.

1 голос
/ 09 мая 2011

Я реструктурировал ваш запрос, чтобы, как мы надеемся, предложить значительное время для повышения производительности.При использовании STRAIGHT_JOIN MySQL говорит, что нужно делать в указанном вами порядке (или я настроил здесь).Псевдоним самого первого запроса «PreQuery» НАЧИНАЕТСЯ с ваших критериев комплекта импорта и универсального импорта, для импорта учетной записи в учетную запись ... Предварительно применив предложение WHERE (и, как вы могли бы проверить, добавьтеОГРАНИЧИТЕ ЗДЕСЬ ЗДЕСЬ) вы предварительно присоединяетесь к этим таблицам и получаете их сразу, прежде чем тратить время на попытки получить информацию о клиентах, адресе и т. Д.В этом запросе я скорректировал объединения join / left, чтобы лучше показать взаимосвязь базовых связанных таблиц (в первую очередь для тех, кто читает в).

Как заметил другой человек, то, что я сделал вPREQUERY может быть основой записей "Account.ID" в основном списке предварительных запросов, используемом для просмотра и доступности страниц.Мне было бы интересно узнать, насколько это эффективно для вашего существующего, особенно в предельном диапазоне 10 000.

PREQUERY получает уникальные элементы (включая идентификатор учетной записи, используемый в нисходящем направлении, банк, месяц, год и категорию), поэтому эти таблицыне нужно возвращаться в оставшуюся часть процесса присоединения.

SELECT STRAIGHT_JOIN
      PreQuery.*,
      customer.customer_number,
      customer.name,
      customer.has_bad_address,
      address.line1,
      address.line2,
      address.city,
      state.name,
      address.zip,
      po_box.line1,
      po_box.line2,
      po_box.city,
      po_state.name,
      po_box.zip,
      customer.date_of_birth,
      northway_account.cffna,
      northway_account.cfinsc,
      customer.deceased,
      customer.social_security_number,
      customer.has_internet_banking,
      customer.safe_deposit_box,
      account.has_bill_pay,
      account.has_e_statement,
      branch.number,
      northway_product.code,
      macatawa_product.code,
      account.account_number,
      account.available_line,
      view_macatawa_atm_card.number,
      view_macatawa_debit_card.number,
      uc.code use_class,
      account.open_date,
      account.balance,
      account.affinion,
      northway_account.ytdsc,
      northway_account.ytdodf,
      northway_account.ytdnsf,
      northway_account.rtckcy,
      northway_account.rtckwy,
      northway_account.odwvey,
      northway_account.ytdscw,
      northway_account.feeytd,
      customer.do_not_mail,
      northway_account.aledq1,
      northway_account.aledq2,
      northway_account.aledq3,
      northway_account.aledq4,
      northway_account.acolq1,
      northway_account.acolq2,
      northway_account.acolq3,
      northway_account.acolq4,
      o.officer_number,
      northway_account.avg_bal_1,
      northway_account.avg_bal_2,
      northway_account.avg_bal_3,
      account.maturity_date,
      account.interest_rate,
      northway_account.asslc,
      northway_account.paidlc,
      northway_account.lnuchg,
      northway_account.ytdlc,
      northway_account.extfee,
      northway_account.penamt,
      northway_account.cdytdwaive,
      northway_account.cdterm,
      northway_account.cdtcod,
      account.date_of_last_statement,
      northway_account.statement_cycle,
      northway_account.cfna1,
      northway_account.cfna2,
      northway_account.cfna3,
      northway_account.cfna4,
      northway_account.cfcity,
      northway_account.cfstate,
      northway_account.cfzip,
      northway_account.actype,
      northway_account.sccode,
      macatawa_account.account_type_code,
      macatawa_account.account_type_code_description,
      macatawa_account.advance_code,
      macatawa_account.amount_last_advance,
      macatawa_account.amount_last_payment,
      macatawa_account.available_credit,
      macatawa_account.balance_last_statement,
      macatawa_account.billing_day,
      macatawa_account.birthday_3,
      macatawa_account.birthday_name_2,
      macatawa_account.ceiling_rate,
      macatawa_account.class_code,
      macatawa_account.classified_doubtful,
      macatawa_account.classified_loss,
      macatawa_account.classified_special,
      macatawa_account.classified_substandard,
      macatawa_account.closed_account_flag,
      macatawa_account.closing_balance,
      macatawa_account.compounding_code,
      macatawa_account.cost_center_full,
      macatawa_account.cytd_aggregate_balance,
      macatawa_account.cytd_amount_of_advances,
      macatawa_account.cytd_amount_of_payments,
      macatawa_account.cytd_average_balance,
      macatawa_account.cytd_average_principal_balance,
      macatawa_account.cytd_interest_paid,
      macatawa_account.cytd_number_items_nsf,
      macatawa_account.cytd_number_of_advanes,
      macatawa_account.cytd_number_of_payments,
      macatawa_account.cytd_number_times_od,
      macatawa_account.cytd_other_charges,
      macatawa_account.cytd_other_charges_waived,
      macatawa_account.cytd_reporting_points,
      macatawa_account.cytd_service_charge,
      macatawa_account.cytd_service_charge_waived,
      macatawa_account.date_closed,
      macatawa_account.date_last_activity,
      macatawa_account.date_last_advance,
      macatawa_account.date_last_payment,
      macatawa_account.date_paid_off,
      macatawa_account.ddl_code,
      macatawa_account.deposit_rate_index,
      macatawa_account.employee_officer_director_full_desc,
      macatawa_account.floor_rate,
      macatawa_account.handling_code,
      macatawa_account.how_paid_code,
      macatawa_account.interest_frequency,
      macatawa_account.ira_plan,
      macatawa_account.load_rate_code,
      macatawa_account.loan_rate_code,
      macatawa_account.loan_rating_code,
      macatawa_account.loan_rating_code_1_full_desc,
      macatawa_account.loan_rating_code_2_full_desc,
      macatawa_account.loan_rating_code_3_full_desc,
      macatawa_account.loan_to_value_ratio,
      macatawa_account.maximum_credit,
      macatawa_account.miscellaneous_code_full_desc,
      macatawa_account.months_to_maturity,
      macatawa_account.msa_code,
      macatawa_account.mtd_agg_available_balance,
      macatawa_account.naics_code,
      macatawa_account.name_2,
      macatawa_account.name_3,
      macatawa_account.name_line,
      macatawa_account.name_line_2,
      macatawa_account.name_line_3,
      macatawa_account.name_line_1,
      macatawa_account.net_payoff,
      macatawa_account.opened_by_responsibility_code_full,
      macatawa_account.original_issue_date,
      macatawa_account.original_maturity_date,
      macatawa_account.original_note_amount,
      macatawa_account.original_note_date,
      macatawa_account.original_prepaid_fees,
      macatawa_account.participation_placed_code,
      macatawa_account.participation_priority_code,
      macatawa_account.pay_to_account,
      macatawa_account.payment_code,
      macatawa_account.payoff_principal_balance,
      macatawa_account.percent_participated_code,
      macatawa_account.pmtd_number_deposit_type_1,
      macatawa_account.pmtd_number_deposit_type_2,
      macatawa_account.pmtd_number_deposit_type_3,
      macatawa_account.pmtd_number_type_1,
      macatawa_account.pmtd_number_type_2,
      macatawa_account.pmtd_number_type_6,
      macatawa_account.pmtd_number_type_8,
      macatawa_account.pmtd_number_type_9,
      macatawa_account.principal,
      macatawa_account.purpose_code,
      macatawa_account.purpose_code_full_desc,
      macatawa_account.pytd_number_of_items_nsf,
      macatawa_account.pytd_number_of_times_od,
      macatawa_account.rate_adjuster,
      macatawa_account.rate_over_split,
      macatawa_account.rate_under_split,
      macatawa_account.renewal_code,
      macatawa_account.renewal_date,
      macatawa_account.responsibility_code_full,
      macatawa_account.secured_unsecured_code,
      macatawa_account.short_first_name_1,
      macatawa_account.short_first_name_2,
      macatawa_account.short_first_name_3,
      macatawa_account.short_last_name_1,
      macatawa_account.short_last_name_2,
      macatawa_account.short_last_name_3,
      macatawa_account.statement_cycle,
      macatawa_account.statement_rate,
      macatawa_account.status_code,
      macatawa_account.tax_id_number_name_2,
      macatawa_account.tax_id_number_name_3,
      macatawa_account.teller_alert_1,
      macatawa_account.teller_alert_2,
      macatawa_account.teller_alert_3,
      macatawa_account.term,
      macatawa_account.term_code,
      macatawa_account.times_past_due_01_29,
      macatawa_account.times_past_due_01_to_29_days,
      macatawa_account.times_past_due_30_59,
      macatawa_account.times_past_due_30_to_59_days,
      macatawa_account.times_past_due_60_89,
      macatawa_account.times_past_due_60_to_89_days,
      macatawa_account.times_past_due_over_90,
      macatawa_account.times_past_due_over_90_days,
      macatawa_account.tin_code_name_1,
      macatawa_account.tin_code_name,
      macatawa_account.tin_code_name_2,
      macatawa_account.tin_code_name_3,
      macatawa_account.total_amount_past_due,
      macatawa_account.waiver_od_charge,
      macatawa_account.waiver_od_charge_description,
      macatawa_account.waiver_service_charge_code,
      macatawa_account.waiver_transfer_advance_fee,
      macatawa_account.short_first_name,
      macatawa_account.short_last_name          
FROM
   ( SELECT STRAIGHT_JOIN DISTINCT
         b.name bank,
         ib.YEAR,
         ib.MONTH,
         ip.category,
         Account.ID
         FROM import_bundle ib 
            JOIN generic_import gi ON ib.id = gi.import_bundle_id
               JOIN account_import AI ON gi.id = ai.generic_import_id
                  JOIN Account ON AI.ID = account.account_import_id 
               JOIN import_profile ip ON gi.import_profile_id = ip.id
            JOIN bank b ib.Bank_ID = b.id
      WHERE
            IB.ID = 95
         AND IB.Active = 1
         AND GI.Active = 1
      LIMIT 1000 ) PreQuery
   JOIN Account on PreQuery.ID = Account.ID
      JOIN Customer on Account.Customer_ID = Customer.ID
      JOIN Officer on Account.Officer_ID = Officer.ID
      LEFT JOIN branch ON Account.branch_id = branch.id
      LEFT JOIN cd_type ON account.cd_type_id = cd_type.id
      LEFT JOIN use_class uc ON account.use_class_id = uc.id
      LEFT JOIN account_type at ON account.account_type_id = at.id
      LEFT JOIN northway_account ON account.id = northway_account.account_id
      LEFT JOIN macatawa_account ON account.id = macatawa_account.account_id
      LEFT JOIN view_macatawa_debit_card ON account.id = view_macatawa_debit_card.account_id
      LEFT JOIN view_macatawa_atm_card ON account.id = view_macatawa_atm_card.account_id
      LEFT JOIN original_address OA ON Account.ID = OA.account_id

      JOIN Account_Address AA ON Account.ID = AA.account_id
         JOIN address ON AA.address_id = address.id
            JOIN state ON address.state_id = state.id

      LEFT JOIN Account_po_box APB ON Account.ID = APB.account_id
         LEFT JOIN address po_box ON APB.address_id = po_box.id
            LEFT JOIN state po_state ON po_box.state_id = po_state.id

      LEFT JOIN Account_macatawa_product amp ON account.id = amp.account_id
         LEFT JOIN macatawa_product ON amp.macatawa_product_id = macatawa_product.id
            LEFT JOIN product_type pt ON macatawa_product.product_type_id = pt.id
            LEFT JOIN harte_hanks_service_category hhsc ON macatawa_product.harte_hanks_service_category_id = hhsc.id
            LEFT JOIN core_file_type cft ON macatawa_product.core_file_type_id = cft.id 

      LEFT JOIN Account_northway_product anp ON account.id = anp.account_id
         LEFT JOIN northway_product ON anp.northway_product_id = northway_product.id
0 голосов
/ 05 мая 2011

Нелинейное увеличение времени выборки, вероятно, является результатом заполнения ключевых буферов и, возможно, других проблем, связанных с памятью. Вы должны оптимизировать запрос, используя EXPLAIN, чтобы максимально использовать индексы, и настроить параметры сервера MySQL.

...