Griboed0ff
07-09-2021, 12:23
Доброго времени суток! Есть большая таблица csv 1.2ГБ, которая постоянно дополняется данными в конец таблицы. В таблице 52 столбца и уже более 20 миллионов строк. Каждая строка имеет столбец с именем ПК, по которому и происходит поиск. Как и у всех больших таблиц имеется проблема с производительностью обработки данных Частично получается решить проблему с использованием фреймворков напрямую, но не хватает знаний, чтобы добиться приемлемой скорости.
Сама задача такова:
1) Взять список имен ПК из AD, их примерно 14000. -решено
2) найти для каждого имени ПК в таблице строку с последними данными,ориентируясь по дате. Так же избежать строки, которые в столбце пинг имеют значение "NO". - ищу решение
3) экспортировать строки найденные ранее в файл csv, с теми же заголовками и без изменения данных. -решено
Проблема возникает именно со вторым пунктом, так как поиск данных для одного имени ПК и выбор самой старшей строки, занимает от 0.1-10сек. Обработка всего списка занимает ~8 часов.
По второму пункту:
Решил отзеркалить таблицу снизу вверх, чтобы вверху таблицы оказались самые свежие данные- это занимает примерно 15-20 минут на это действие. Как перебирать таблицу с конца при поиске так и не понял. Но данное действие значительно укорило процесс, так как нужное значение почти всегда находится среди первых ~20000 строк.
"Data";"Ping";"Region";"B_S_TT";"System_Unit_Name";"System_Unit_Manufacturer";"System_Unit_Model";"Motherboard_SN";"Adapter_IPv4";"Adapter_Mac";"Adapter_Name";"Adapter_Type";"Adapter_Speed";"Monitor_1_model";"Monitor_1_SN";"Monitor_2_model";"Monitor_2_SN";"Router_Manufacturer";"Router_Model";"Router_SN";"Processor";"DDRx";"kolichestvo_Slots_all";"kolichestvo_Slots_free";"PhysicalMemory_all";"Slot_1_size";"Slot_1_speed";"Slot_1_manufacturer";"Slot_2_size";"Slot_2_speed";"Slot_2_manufacturer";"Slot_3_size";"Slot_3_speed";"Slot_3_manufacturer";"Slot_4_size";"Slot_4_speed";"Slot_4_manufacturer";"OS";"x64_x86";"disk_1_name";"disk_1_size";"disk_1_type";"disk_2_name";"disk_2_size";"disk_2_type";"disk_3_name";"disk_3_size";"disk_3_type";"disk_4_name";"disk_4_size";"disk_4_type";"shk"
"07.09.2021";"Yes";"msk";"b";"GO-DD1155";"Hewlett-Packard";"HP Compaq 6200 Pro MT PC";"RUA23101TK";"10.243.78.51";"A0:B3:CC:F7:8A:B7";"Intel(R) 82579LM Gigabit Network Connection";"Ethernet 802.3";"1000";"HP E231 ";"3CQ4271J2H ";"";"";;;;"Intel(R) Core(TM) i5-2400 CPU @ 3.10GHz";"DDR3";"4";"3";"4";"4";"1333";"Samsung ";"0";"";"";"0";"";"";"0";"";"";"Майкрософт Windows 10 Pro";"64-разрядная";"ST3500413AS";"466";"HDD";"";"0";"";;"0";"";;"0";"";"no info"
"07.09.2021";"Yes";"msk";"b";"GO-DG584";"Hewlett-Packard";"HP ProDesk 400 G2 MT";"CZC44843RZ";"10.243.78.25";"A0:D3:C1:50:07:54";"Realtek PCIe GBE Family Controller";"Ethernet 802.3";"100";"";"";"";"";;;;"Intel(R) Core(TM) i5-4590S CPU @ 3.00GHz";"DDR3";"2";"0";"8";"4";"1600";"Micron";"4";"1600";"Micron";"0";"";"";"0";"";"";"Майкрософт Windows 10 Pro";"64-разрядная";"ST500DM002-1BD142";"466";"HDD";"";"0";"";;"0";"";;"0";"";"no info"
"07.09.2021";"Yes";"msk";"b";"GO-DG208";"Hewlett-Packard";"HP ProDesk 400 G2 MT";"CZC44843LL";"10.243.72.16";"A0:D3:C1:4D:53:B0";"Realtek PCIe GBE Family Controller";"Ethernet 802.3";"100";"HP E231 ";"3CQ4360H20 ";"";"";;;;"Intel(R) Core(TM) i5-4590S CPU @ 3.00GHz";"DDR3";"2";"0";"8";"4";"1600";"0000";"4";"1600";"0000";"0";"";"";"0";"";"";"Майкрософт Windows 10 Pro";"64-разрядная";"ST500DM002-1BD142";"466";"HDD";"";"0";"";;"0";"";;"0";"";"no info"
"07.09.2021";"No";"msk";"b";"go-nd6671";" ";" ";" ";" ";" ";" ";" ";" ";" ";" ";" ";" ";" ";" ";" ";" ";" ";" ";" ";" ";" ";" ";" ";" ";" ";" ";" ";" ";" ";" ";" ";" ";" ";" ";" ";" ";" ";" ";" ";" ";" ";" ";" ";" ";" ";" ";" "
"07.09.2021";"Yes";"msk";"b";"GO-DG404";"Hewlett-Packard";"HP Compaq Pro 6300 MT";"RUA2470C98";"10.243.66.171";"B4:B5:2F:DA:14:13";"Intel(R) 82579LM Gigabit Network Connection";"Ethernet 802.3";"100";"HP E231 ";"3CQ4360FRM ";"";"";;;;"Intel(R) Core(TM) i5-3470 CPU @ 3.20GHz";"DDR3";"4";"2";"8";"4";"1600";"Samsung";"4";"1600";"Kingston";"0";"";"";"0";"";"";"Майкрософт Windows 10 Pro";"64-разрядная";"Hitachi HDS721050CLA660";"466";"HDD";"";"0";"";;"0";"";;"0";"";"no info"
"07.09.2021";"No";"msk";"b";"GO-NG433";" ";" ";" ";" ";" ";" ";" ";" ";" ";" ";" ";" ";" ";" ";" ";" ";" ";" ";" ";" ";" ";" ";" ";" ";" ";" ";" ";" ";" ";" ";" ";" ";" ";" ";" ";" ";" ";" ";" ";" ";" ";" ";" ";" ";" ";" ";" "
часть скрипта где все описанное происходит
# Считает количество строк в файле
[int]$linesInFile = 0
$reader = New-Object IO.StreamReader $outfile
while($reader.ReadLine() -ne $null){$linesInFile++}
$linesInFile
# отзеркаливание таблицы снизу вверх
$lines = [IO.File]::ReadAllLines($outfile)
for ($str = $linesInFile;$str -ne 0;$str--){
# Обращается к строке по номеру и экспортирует
$str
$lines[$str]|Add-Content -Encoding UTF8 $outfile2}
$OU | ForEach {
$all = get-adcomputer -Filter {ObjectClass -eq 'Computer'} -SearchBase $_ -Properties CanonicalName,SamAccountName,CN,lastLogonTimeStamp,whenChanged,memberof
ForEach ($all in $all){
$rt= $all.CN
$rt
select-string -path $outfile2 -list -pattern "$rt" | add-Content $outfile3 -Encoding utf8
}}
Я пытался отсортировать таблицу по дате стандартными способами, но они занимают намного больше времени и полностью занимают ОЗУ. Способ, который выбрал я не кушает ОЗУ, но я был бы рад избежать шага сортировки вообще и начинать поиск нужных данных с конца таблицы.
Возможно есть способ, который позволит искать сразу множество имен ПК, например 14000 имен, чтобы не перебирать всю таблицу снова для каждого значения. МБ время поиска сократить за счет поиска значения не во всей строке, а только в указанном столбце этой строки, а потом уже отправлять эту строку на экспорт. Ищу любые способы ускорения процесса, на данный момент ОЗУ не страдает и ЦПУ тоже. Ну и буду рад, если кто-нибудь поможет оптимизировать код, а скорее всего есть не нужные моменты.
Сама задача такова:
1) Взять список имен ПК из AD, их примерно 14000. -решено
2) найти для каждого имени ПК в таблице строку с последними данными,ориентируясь по дате. Так же избежать строки, которые в столбце пинг имеют значение "NO". - ищу решение
3) экспортировать строки найденные ранее в файл csv, с теми же заголовками и без изменения данных. -решено
Проблема возникает именно со вторым пунктом, так как поиск данных для одного имени ПК и выбор самой старшей строки, занимает от 0.1-10сек. Обработка всего списка занимает ~8 часов.
По второму пункту:
Решил отзеркалить таблицу снизу вверх, чтобы вверху таблицы оказались самые свежие данные- это занимает примерно 15-20 минут на это действие. Как перебирать таблицу с конца при поиске так и не понял. Но данное действие значительно укорило процесс, так как нужное значение почти всегда находится среди первых ~20000 строк.
"Data";"Ping";"Region";"B_S_TT";"System_Unit_Name";"System_Unit_Manufacturer";"System_Unit_Model";"Motherboard_SN";"Adapter_IPv4";"Adapter_Mac";"Adapter_Name";"Adapter_Type";"Adapter_Speed";"Monitor_1_model";"Monitor_1_SN";"Monitor_2_model";"Monitor_2_SN";"Router_Manufacturer";"Router_Model";"Router_SN";"Processor";"DDRx";"kolichestvo_Slots_all";"kolichestvo_Slots_free";"PhysicalMemory_all";"Slot_1_size";"Slot_1_speed";"Slot_1_manufacturer";"Slot_2_size";"Slot_2_speed";"Slot_2_manufacturer";"Slot_3_size";"Slot_3_speed";"Slot_3_manufacturer";"Slot_4_size";"Slot_4_speed";"Slot_4_manufacturer";"OS";"x64_x86";"disk_1_name";"disk_1_size";"disk_1_type";"disk_2_name";"disk_2_size";"disk_2_type";"disk_3_name";"disk_3_size";"disk_3_type";"disk_4_name";"disk_4_size";"disk_4_type";"shk"
"07.09.2021";"Yes";"msk";"b";"GO-DD1155";"Hewlett-Packard";"HP Compaq 6200 Pro MT PC";"RUA23101TK";"10.243.78.51";"A0:B3:CC:F7:8A:B7";"Intel(R) 82579LM Gigabit Network Connection";"Ethernet 802.3";"1000";"HP E231 ";"3CQ4271J2H ";"";"";;;;"Intel(R) Core(TM) i5-2400 CPU @ 3.10GHz";"DDR3";"4";"3";"4";"4";"1333";"Samsung ";"0";"";"";"0";"";"";"0";"";"";"Майкрософт Windows 10 Pro";"64-разрядная";"ST3500413AS";"466";"HDD";"";"0";"";;"0";"";;"0";"";"no info"
"07.09.2021";"Yes";"msk";"b";"GO-DG584";"Hewlett-Packard";"HP ProDesk 400 G2 MT";"CZC44843RZ";"10.243.78.25";"A0:D3:C1:50:07:54";"Realtek PCIe GBE Family Controller";"Ethernet 802.3";"100";"";"";"";"";;;;"Intel(R) Core(TM) i5-4590S CPU @ 3.00GHz";"DDR3";"2";"0";"8";"4";"1600";"Micron";"4";"1600";"Micron";"0";"";"";"0";"";"";"Майкрософт Windows 10 Pro";"64-разрядная";"ST500DM002-1BD142";"466";"HDD";"";"0";"";;"0";"";;"0";"";"no info"
"07.09.2021";"Yes";"msk";"b";"GO-DG208";"Hewlett-Packard";"HP ProDesk 400 G2 MT";"CZC44843LL";"10.243.72.16";"A0:D3:C1:4D:53:B0";"Realtek PCIe GBE Family Controller";"Ethernet 802.3";"100";"HP E231 ";"3CQ4360H20 ";"";"";;;;"Intel(R) Core(TM) i5-4590S CPU @ 3.00GHz";"DDR3";"2";"0";"8";"4";"1600";"0000";"4";"1600";"0000";"0";"";"";"0";"";"";"Майкрософт Windows 10 Pro";"64-разрядная";"ST500DM002-1BD142";"466";"HDD";"";"0";"";;"0";"";;"0";"";"no info"
"07.09.2021";"No";"msk";"b";"go-nd6671";" ";" ";" ";" ";" ";" ";" ";" ";" ";" ";" ";" ";" ";" ";" ";" ";" ";" ";" ";" ";" ";" ";" ";" ";" ";" ";" ";" ";" ";" ";" ";" ";" ";" ";" ";" ";" ";" ";" ";" ";" ";" ";" ";" ";" ";" ";" "
"07.09.2021";"Yes";"msk";"b";"GO-DG404";"Hewlett-Packard";"HP Compaq Pro 6300 MT";"RUA2470C98";"10.243.66.171";"B4:B5:2F:DA:14:13";"Intel(R) 82579LM Gigabit Network Connection";"Ethernet 802.3";"100";"HP E231 ";"3CQ4360FRM ";"";"";;;;"Intel(R) Core(TM) i5-3470 CPU @ 3.20GHz";"DDR3";"4";"2";"8";"4";"1600";"Samsung";"4";"1600";"Kingston";"0";"";"";"0";"";"";"Майкрософт Windows 10 Pro";"64-разрядная";"Hitachi HDS721050CLA660";"466";"HDD";"";"0";"";;"0";"";;"0";"";"no info"
"07.09.2021";"No";"msk";"b";"GO-NG433";" ";" ";" ";" ";" ";" ";" ";" ";" ";" ";" ";" ";" ";" ";" ";" ";" ";" ";" ";" ";" ";" ";" ";" ";" ";" ";" ";" ";" ";" ";" ";" ";" ";" ";" ";" ";" ";" ";" ";" ";" ";" ";" ";" ";" ";" ";" "
часть скрипта где все описанное происходит
# Считает количество строк в файле
[int]$linesInFile = 0
$reader = New-Object IO.StreamReader $outfile
while($reader.ReadLine() -ne $null){$linesInFile++}
$linesInFile
# отзеркаливание таблицы снизу вверх
$lines = [IO.File]::ReadAllLines($outfile)
for ($str = $linesInFile;$str -ne 0;$str--){
# Обращается к строке по номеру и экспортирует
$str
$lines[$str]|Add-Content -Encoding UTF8 $outfile2}
$OU | ForEach {
$all = get-adcomputer -Filter {ObjectClass -eq 'Computer'} -SearchBase $_ -Properties CanonicalName,SamAccountName,CN,lastLogonTimeStamp,whenChanged,memberof
ForEach ($all in $all){
$rt= $all.CN
$rt
select-string -path $outfile2 -list -pattern "$rt" | add-Content $outfile3 -Encoding utf8
}}
Я пытался отсортировать таблицу по дате стандартными способами, но они занимают намного больше времени и полностью занимают ОЗУ. Способ, который выбрал я не кушает ОЗУ, но я был бы рад избежать шага сортировки вообще и начинать поиск нужных данных с конца таблицы.
Возможно есть способ, который позволит искать сразу множество имен ПК, например 14000 имен, чтобы не перебирать всю таблицу снова для каждого значения. МБ время поиска сократить за счет поиска значения не во всей строке, а только в указанном столбце этой строки, а потом уже отправлять эту строку на экспорт. Ищу любые способы ускорения процесса, на данный момент ОЗУ не страдает и ЦПУ тоже. Ну и буду рад, если кто-нибудь поможет оптимизировать код, а скорее всего есть не нужные моменты.