select va.*, vm.license_plate , wsm.work_site_name, sd2.dept_name as project_name from vehicle_alarm va inner join vehicle_manage vm on vm.id = va.vehicle_id inner join work_site_manage wsm on wsm.id = vm.work_site_id inner join sys_dept sd1 on va.company_id = sd1.dept_id and sd1.del_flag = '0' and sd1.dept_type = '1' inner join sys_dept sd2 on va.project_id = sd2.dept_id and sd2.del_flag = '0' and sd2.dept_type = '3' where wsm.del_flag = '0' and wsm.del_flag = '0' and vm.del_flag = '0' and vm.license_plate like '%川ADG59%' and wsm.project_id in ( 114 , 118 , 121 , 123 , 125 , 127 , 129 , 131 , 133 , 135 , 137 , 139 , 141 , 143 , 150 , 157 , 3004 , 3016 , 3017 , 3044 ) order by va.alarm_start_time desc 这一行and vm.license_plate like '%川ADG59%'导致查询时间过长 pgsql数据库

时间: 2025-07-28 18:00:31 AIGC 浏览: 35
<think>我们面对的问题是:在PostgreSQL中优化包含模糊查询`LIKE '%川ADG59%'`的SQL性能,该查询涉及多表连接(`vehicle_alarm`和`vehicle_manage`等)。由于前导通配符`%`导致无法使用索引,需要进行优化。 根据引用[2]和引用[4],PostgreSQL中模糊查询的优化方法包括使用索引(如b-tree索引、gin倒排索引)以及避免全表扫描。结合引用[4]中提到的《PostgreSQL模糊查询优化》,我们可以采用以下方案: ### 优化方案 #### 1. **使用表达式索引(反转函数索引)** 原理:将字符串反转后存储,并创建索引,将前导模糊查询转换为后导模糊查询。 ```sql -- 在vehicle_manage表上添加反转列和索引 ALTER TABLE vehicle_manage ADD COLUMN license_plate_rev text; UPDATE vehicle_manage SET license_plate_rev = reverse(license_plate); CREATE INDEX idx_vm_plate_rev ON vehicle_manage (license_plate_rev); -- 修改查询条件 SELECT va.*, vm.license_plate, wsm.work_site_name, sd2.dept_name as project_name FROM vehicle_alarm va INNER JOIN vehicle_manage vm ON vm.id = va.vehicle_id INNER JOIN work_site_manage wsm ON wsm.id = vm.work_site_id INNER JOIN sys_dept sd1 ON va.company_id = sd1.dept_id AND sd1.del_flag = '0' AND sd1.dept_type = '1' INNER JOIN sys_dept sd2 ON va.project_id = sd2.dept_id AND sd2.del_flag = '0' AND sd2.dept_type = '3' WHERE wsm.del_flag = '0' AND vm.del_flag = '0' AND vm.license_plate_rev LIKE reverse('川ADG59') || '%' -- 使用反转列索引 ORDER BY va.alarm_start_time DESC; ``` **优点**:利用索引加速查询,避免全表扫描。 #### 2. **使用pg_trgm扩展和GIN索引(推荐)** PostgreSQL的pg_trgm扩展支持任意位置的模糊查询索引。引用[4]提到gin倒排索引可用于模糊查询优化。 ```sql -- 启用pg_trgm扩展 CREATE EXTENSION IF NOT EXISTS pg_trgm; -- 在vehicle_manage.license_plate上创建GIN索引 CREATE INDEX idx_vm_plate_gin ON vehicle_manage USING gin (license_plate gin_trgm_ops); -- 修改查询条件(使用更高效的写法) SELECT va.*, vm.license_plate, wsm.work_site_name, sd2.dept_name as project_name FROM vehicle_alarm va INNER JOIN vehicle_manage vm ON vm.id = va.vehicle_id INNER JOIN work_site_manage wsm ON wsm.id = vm.work_site_id INNER JOIN sys_dept sd1 ON va.company_id = sd1.dept_id AND sd1.del_flag = '0' AND sd1.dept_type = '1' INNER JOIN sys_dept sd2 ON va.project_id = sd2.dept_id AND sd2.del_flag = '0' AND sd2.dept_type = '3' WHERE wsm.del_flag = '0' AND vm.del_flag = '0' AND vm.license_plate LIKE '%川ADG59%' -- 原始条件,但可以利用GIN索引 ORDER BY va.alarm_start_time DESC; ``` **优点**:支持任意位置的模糊匹配,索引效率高。 #### 3. **减少连接的数据量** 先通过子查询或CTE缩小`vehicle_manage`表的范围,再与其他表连接。 ```sql WITH vm_cte AS ( SELECT id, license_plate, work_site_id FROM vehicle_manage WHERE license_plate LIKE '%川ADG59%' -- 如果使用pg_trgm索引,这里会先走索引 AND del_flag = '0' ) SELECT va.*, vm.license_plate, wsm.work_site_name, sd2.dept_name as project_name FROM vehicle_alarm va INNER JOIN vm_cte vm ON vm.id = va.vehicle_id INNER JOIN work_site_manage wsm ON wsm.id = vm.work_site_id AND wsm.del_flag = '0' INNER JOIN sys_dept sd1 ON va.company_id = sd1.dept_id AND sd1.del_flag = '0' AND sd1.dept_type = '1' INNER JOIN sys_dept sd2 ON va.project_id = sd2.dept_id AND sd2.del_flag = '0' AND sd2.dept_type = '3' ORDER BY va.alarm_start_time DESC; ``` **优点**:先过滤车辆表,减少后续连接的数据量。 ### 性能对比 | 方法 | 索引类型 | 是否支持前导`%` | 适用场景 | |--------------------|--------------|----------------|------------------------| | **表达式索引(反转)** | B-tree | ✅ | 简单模糊查询 | | **pg_trgm扩展** | GIN倒排索引 | ✅ | 复杂模糊查询(推荐) | | **子查询过滤** | 依赖原索引 | ✅ | 减少连接数据量 | ### 实施步骤 1. **评估数据特征**:检查`vehicle_manage`表中`license_plate`字段的分布和长度。 2. **选择索引方案**: - 如果车牌长度固定(如7位),优先使用反转索引。 - 如果车牌长度不固定或需要更灵活的匹配,使用pg_trgm的GIN索引。 3. **创建索引**: ```sql -- 方案1:反转索引 ALTER TABLE vehicle_manage ADD COLUMN license_plate_rev text; UPDATE vehicle_manage SET license_plate_rev = reverse(license_plate); CREATE INDEX idx_vm_plate_rev ON vehicle_manage (license_plate_rev); -- 方案2:pg_trgm索引 CREATE EXTENSION IF NOT EXISTS pg_trgm; CREATE INDEX idx_vm_plate_gin ON vehicle_manage USING gin (license_plate gin_trgm_ops); ``` 4. **重写查询**:根据选择的索引方案调整WHERE条件。 5. **验证执行计划**:使用`EXPLAIN ANALYZE`确认索引被使用。 > ⚠️ **注意**: > - 添加索引会占用存储空间,并影响写操作性能。 > - 使用pg_trgm时,模糊查询的字符串长度不能太短(至少3个字符),否则可能退化为全表扫描。 --- §§相关问题§§ 1. 如何验证PostgreSQL中索引是否被查询使用? 2. pg_trgm扩展对多字节字符(如中文)的支持如何? 3. 在哪些场景下反转索引比pg_trgm更高效? 4. 如何监控PostgreSQL中慢查询的性能变化? [^2]: PostgreSQL模糊查询优化方法 [^4]: PostgreSQL模糊查询优化及索引选择</think>### PostgreSQL模糊查询性能优化方案 针对您的查询中`LIKE '%川ADG59%'`导致的性能问题,以下是针对PostgreSQL的优化方案(基于引用[2][4]的模糊查询优化原则): #### 1. **使用pg_trgm扩展和GIN索引(推荐方案)** ```sql -- 启用pg_trgm扩展(需超级用户权限) CREATE EXTENSION IF NOT EXISTS pg_trgm; -- 在vehicle_manage.license_plate上创建GIN索引 CREATE INDEX idx_vm_plate_gin ON vehicle_manage USING gin (license_plate gin_trgm_ops); -- 优化后的查询(使用索引加速) SELECT va.*, vm.license_plate, wsm.work_site_name, sd2.dept_name as project_name FROM vehicle_alarm va INNER JOIN vehicle_manage vm ON vm.id = va.vehicle_id INNER JOIN work_site_manage wsm ON wsm.id = vm.work_site_id INNER JOIN sys_dept sd1 ON va.company_id = sd1.dept_id AND sd1.del_flag = '0' AND sd1.dept_type = '1' INNER JOIN sys_dept sd2 ON va.project_id = sd2.dept_id AND sd2.del_flag = '0' AND sd2.dept_type = '3' WHERE wsm.del_flag = '0' AND vm.del_flag = '0' AND vm.license_plate LIKE '%川ADG59%' -- 现在可使用索引 ORDER BY va.alarm_start_time DESC; ``` **原理**: `pg_trgm`将文本拆分为3字符片段(trigram),GIN索引支持任意位置的模糊匹配[^2]。此方案对中文支持良好(需确保数据库编码为UTF-8)。 #### 2. **反转列+函数索引(替代方案)** ```sql -- 添加反转列 ALTER TABLE vehicle_manage ADD COLUMN license_plate_rev text; -- 填充反转数据 UPDATE vehicle_manage SET license_plate_rev = reverse(license_plate); -- 创建函数索引 CREATE INDEX idx_vm_plate_rev ON vehicle_manage (license_plate_rev); -- 修改查询条件 SELECT ... WHERE reverse(vm.license_plate) LIKE reverse('川ADG59') || '%' ``` **适用场景**:当无法使用pg_trgm时,此方案将`LIKE '%川ADG59%'`转换为`LIKE '95GDA川%'`(后导通配符可走索引)[^4]。 #### 3. **查询重写优化** ```sql WITH filtered_vm AS ( SELECT id, license_plate, work_site_id FROM vehicle_manage WHERE license_plate LIKE '%川ADG59%' -- 先过滤车辆表 AND del_flag = '0' ) SELECT va.*, vm.license_plate, wsm.work_site_name, sd2.dept_name as project_name FROM vehicle_alarm va INNER JOIN filtered_vm vm ON vm.id = va.vehicle_id INNER JOIN work_site_manage wsm ON wsm.id = vm.work_site_id AND wsm.del_flag = '0' INNER JOIN sys_dept sd1 ON va.company_id = sd1.dept_id AND sd1.del_flag = '0' AND sd1.dept_type = '1' INNER JOIN sys_dept sd2 ON va.project_id = sd2.dept_id AND sd2.del_flag = '0' AND sd2.dept_type = '3' ORDER BY va.alarm_start_time DESC; ``` **优势**:通过CTE先缩小数据集,减少后续表连接的数据量。 #### 4. **其他优化措施 - **索引优化**:确保连接字段(如`va.vehicle_id`, `vm.work_site_id`)有B-tree索引 - **统计信息更新**:定期执行`ANALYZE vehicle_manage;` - **查询监控**:使用`pg_stat_statements`监控慢查询[^4] ### 性能对比 | 方案 | 索引类型 | 响应时间 | 存储开销 | 维护复杂度 | |--------------------|--------------|----------|----------|------------| | pg_trgm + GIN | GIN倒排索引 | ★★★★☆ | 较高 | 低 | | 反转列+函数索引 | B-tree | ★★★☆☆ | 中等 | 中 | | 查询重写 | 依赖原索引 | ★★☆☆☆ | 无 | 低 | ### 实施建议 1. **优先选择方案1**(pg_trgm+GIN),尤其当车牌字段较长时 2. 若车牌数据量极大(>1亿行),结合分区表使用 3. 避免在WHERE子句中使用函数包装`license_plate`(如`lower(license_plate)`),这会禁用索引 > 📌 **验证索引使用**:添加`EXPLAIN ANALYZE`前缀查看执行计划,确认是否使用索引: > ```sql > EXPLAIN ANALYZE > SELECT ... WHERE vm.license_plate LIKE '%川ADG59%'; > ``` ---
阅读全文

相关推荐

P2P的连接过程 > OK <3>P2P-FIND-STOPPED [ 8089.449282] [TXRX_WRN] status=6, retry=14, lastRate=0x006f [ 8089.795900] [TXRX_WRN] status=6, retry=14, lastRate=0x006f [ 8089.922671] [TXRX_WRN] status=6, retry=14, lastRate=0x006f [ 8090.371372] [TXRX_WRN] status=6, retry=14, lastRate=0x006f [ 8090.819199] [TXRX_WRN] status=6, retry=14, lastRate=0x006f [ 8091.164441] [TXRX_WRN] status=6, retry=14, lastRate=0x006f <3>P2P-PROV-DISC-PBC-REQ aa:cf:fb:24:3b:bd p2p_dev_addr=aa:cf:fb:24:3b:bd pri_dev_type=10-0050F204-5 name='一加 Ace 5 Pro' config_methods=0x188 dev_capab=0x25 group_capab=0x0 <3>P2P-PROV-DISC-PBC-REQ aa:cf:fb:24:3b:bd p2p_dev_addr=aa:cf:fb:24:3b:bd pri_dev_type=10-0050F204-5 name='一加 Ace 5 Pro' config_methods=0x188 dev_capab=0x25 group_capab=0x0 [ 8091.615929] [TXRX_WRN] status=6, retry=14, lastRate=0x006f [ 8091.859119] [TXRX_WRN] status=6, retry=14, lastRate=0x006f [ 8091.970534] [TXRX_WRN] [ROC_RESTART_STATE_GET_PKTID] [ 8091.977055] [TXRX_WRN] [ROC RESTART ACTIVE ON][Confirm CallBack] [ 8091.984223] [TXRX_WRN] [ROC_RESTART_STATE_GET_PKTID] [ 8091.990452] [STA_WRN] [ROC_RESTART_STATE_IDLE][Cancel ROC] <3>P2P-GO-NEG-SUCCESS role=c[ 8092.020995] ieee80211_do_open: vif_type=2, p2p=1, ch=3, addr=4c:ca:ef:1a:62:2e lient freq=2412 ht40=0 peer_dev=[ 8092.029807] [STA] !!!xradio_vif_setup: id=1, type=2, p2p=1, addr=4c:ca:ef:1a:62:2e aa:cf:fb:24:3b:bd peer_iface=aa:[ 8092.042929] IPv6: ADDRCONF(NETDEV_UP): p2p-p2p0-0: link is not ready cf:fb:24:3b:bd wps_method=PBC <3>CTRL-EVENT-SCAN-RESULTS <3>WPS-AP-AVAILABLE [ 8092.644136] p2p-p2p0-0: authenticate with aa:cf:fb:24:3b:bd (try 1) [ 8092.651468] [STA_WRN] [HT40][xradio_join_work][bss_ht_info]: [ 8092.651468] [primary_chan :0x00000001] [ 8092.651468] [ht_param :0x00000000] [ 8092.651468] [operation_mode:0x00000000] [ 8092.651468] [stbc_param :0x00000000] [ 8092.651468] [basic_set[0] :0x00000000] [ 8092.679458] [STA_WRN] [HT40][xradio_join_work][PhyModeCfg:0x0007] [ 8092.679458] [ModemFlags :0x00000007] [ 8092.679458] [ChWidthCfg :0x00000000] [ 8092.679458] [PriChCfg :0x00000000] [ 8092.679458] [BandCfg :0x00000000] [ 8092.679458] [STBC_Enable :0x00000000] [ 8092.679458] [PreambleCfg :0x00000000] [ 8092.679458] [SGI_Enable :0x00000000] [ 8092.679458] GF_Enable :0x00000000] [ 8092.739352] p2p-p2p0-0: authenticated [ 8092.744231] p2p-p2p0-0: associate with aa:cf:fb:24:3b:bd (try 1) [ 8092.770629] p2p-p2p0-0: RX AssocResp from aa:cf:fb:24:3b:bd (capab=0x1431 status=0 aid=1) [ 8092.780187] p2p-p2p0-0: associated [ 8092.787989] [AP_WRN] [STA] ASSOC is_combo 35 [ 8092.792964] [AP_WRN] [HT40][xradio_bss_info_changed][ht_prot:0x00000000][HtProtMode:0x0000][Green:0x0000] [ 8092.803889] [AP_WRN] [HT40][xradio_bss_info_changed][PhyModeCfg:0x5007] [ 8092.803889] [ModemFlags :0x00000007] [ 8092.803889] [ChWidthCfg :0x00000000] [ 8092.803889] [PriChCfg :0x00000000] [ 8092.803889] [BandCfg :0x00000000] [ 8092.803889] [STBC_Enable :0x00000000] [ 8092.803889] [PreambleCfg :0x00000001] [ 8092.803889] [SGI_Enable :0x00000001] [ 8092.803889] [GF_Enable :0x00000000] [ 8092.853030] [AP_WRN] [STA] ASSOC is_combo 35 [ 8092.871626] [AP_WRN] [HT40][xradio_bss_info_changed][ht_prot:0x00000008][HtProtMode:0x0002][Green:0x0000] [ 8092.891942] [AP_WRN] [HT40][xradio_bss_info_changed][PhyModeCfg:0x5007] [ 8092.891942] [ModemFlags :0x00000007] [ 8092.891942] [ChWidthCfg :0x00000000] [ 8092.891942] [PriChCfg :0x00000000] [ 8092.891942] [BandCfg :0x00000000] [ 8092.891942] [STBC_Enable :0x00000000] [ 8092.891942] [PreambleCfg :0x00000001] [ 8092.891942] [SGI_Enable :0x00000001] [ 8092.891942] [GF_Enable :0x00000000] [ 8093.360037] [TXRX_WRN] [RX] IF=1, No key found. [ 8093.365257] [TXRX_WRN] [RX] IF=1, No key found. [ 8093.370381] [TXRX_WRN] [RX] IF=1, No key found. [ 8093.415659] p2p-p2p0-0: deauthenticating from aa:cf:fb:24:3b:bd by local choice (reason=3) [ 8093.425390] [WSM_WRN] Issue unjoin command(TX). [ 8093.430989] [WSM_WRN] STA mode, send_deauth_to_self [ 8093.436524] [TXRX_WRN] Issue unjoin command(TX) by self. [ 8093.481649] [STA_WRN] !!! xradio_remove_interface: vif_id=1 > 'PING' command failed. Connection to wpa_supplicant lost - trying to reconnect [ 8115.811630] [BH_WRN] miss interrupt! [ 8125.831634] [BH_WRN] miss interrupt! [ 8139.971633] [BH_WRN] miss interrupt!

// 完整查詢 $sqlQuery = $baseQuery . $searchQuery . $orderQuery . $limitQuery; $result = mysqli_query($this->dbConnect, $sqlQuery); $WSMData = array(); while( $WSM = mysqli_fetch_assoc($result) ) { $level1Query = "SELECT COUNT(*) FROM " . $this->dbConnect->real_escape_string($this->htmlTable)." WHERE WSMPID = ".$WSM['WSMID']; $level1Result = mysqli_query($this->dbConnect, $level1Query); $level1Data = mysqli_fetch_row($level1Result); $level1Records = $level1Data[0]; $wsmRows = array(); $wsmRows[] = $WSM['WSMID']?? ''; $wsmRows[] = ''; $wsmRows[] = $WSM['WSMTitle']?? ''; $wsmRows[] = $WSM['WSMURL']?? ''; $wsmRows[] = $WSM['WSMType']?? ''; $wsmRows[] = $WSM['WSMLevel']; $wsmRows[] = $WSM['WSMPID']; $wsmRows[] = '<button type="button" name="update" ID="'.$WSM['WSMID'].'" class="btn btn-warning btn-sm update"></button> <button type="button" name="delete" ID="'.$WSM['WSMID'].'" class="btn btn-danger btn-sm delete" ></button>'; $WSMData[] = $wsmRows; $base1Query = "SELECT * FROM ".$this->htmlTable." WHERE WSMPID = ".$WSM['WSMID']." Order by WSMOrder"; $result1 = mysqli_query($this->dbConnect, $base1Query); while( $WSM1 = mysqli_fetch_assoc($result1) ) { $level2Query = "SELECT COUNT(*) FROM " . $this->dbConnect->real_escape_string($this->htmlTable)." WHERE WSMPID = ".$WSM1['WSMID']; $level2Result = mysqli_query($this->dbConnect, $level2Query); $level2Data = mysqli_fetch_row($level2Result); $level2Records = $level2Data[0]; $wsmRows = array(); $wsmRows[] = $WSM1['WSMID']?? ''; $wsmRows[] = ''; $wsmRows[] = ' ■ '.$WSM1['WSMTitle']; $wsmRows[] = $WSM1['WSMURL']?? ''; $wsmRows[] = $WSM1['WSMType']?? ''; $wsmRows[] = $WSM1['WSMLevel']; $wsmRows[] = $WSM1['WSMPID']; $wsmRows[] = '<button type="button" name="update" ID="'.$WSM1['WSMID'].'" class="btn btn-warning btn-sm update"></button> <button type="button" name="delete" ID="'.$WSM1['WSMID'].'" class="btn btn-danger btn-sm delete" ></button>'; $WSMData[] = $wsmRows; $base2Query = "SELECT * FROM ".$this->htmlTable." WHERE WSMPID = ".$WSM1['WSMID']." Order by WSMOrder"; $result2 = mysqli_query($this->dbConnect, $base2Query); while( $WSM2 = mysqli_fetch_assoc($result2) ) { $wsmRows = array(); $wsmRows[] = $WSM2['WSMID']?? ''; $wsmRows[] = ''; $wsmRows[] = '  ※ '.$WSM2['WSMTitle']?? ''; $wsmRows[] = $WSM2['WSMURL']?? ''; $wsmRows[] = $WSM2['WSMType']?? ''; $wsmRows[] = $WSM2['WSMLevel']; $wsmRows[] = $WSM2['WSMPID']; $wsmRows[] = '<button type="button" name="update" ID="'.$WSM2['WSMID'].'" class="btn btn-warning btn-sm update"></button> <button type="button" name="delete" ID="'.$WSM2['WSMID'].'" class="btn btn-danger btn-sm delete" ></button>'; $WSMData[] = $wsmRows; } } }優化代碼

'------------------------------------------------------------------+ ' Module specification '------------------------------------------------------------------+ ' ' Module Name : ExpWStoQL ' ' Copyright : Yokogawa SCE, 2004 ' ' Author : Jan Worst ' ' Description : Export Worksheet to Quickload file ' ' '------------------------------------------------------------------+ ' Changes .... '------------------------------------------------------------------+ ' Who When Change What '------------------------------------------------------------------+ ' WST Jun-04 exxxx FAST/TOOLS to Excel demo ' WST Oct-05 Add comment column (starting with "#") '------------------------------------------------------------------+ Option Explicit Dim qldws As New qldWorkSheet Dim myWS As New Excel.Worksheet Dim wsAbs As wsAbstract Dim ColInstall As Integer Dim ColUnit As Integer Dim ColTag As Integer Dim ColSub As Integer Dim ColGroupName As Integer Dim ComposedKey As Boolean ' Indicates NAME field missing Dim colQldFields As Collection Dim ColSelected(256) As Boolean ' Shows if column must be exported Dim wsM As WsMacros Public Sub ExpWStoQL(ws As Excel.Worksheet, _ qlFile As String, _ Append As Boolean, _ SelectedRowsOnly As Boolean, _ SelectedColumnsOnly As Boolean, _ WriteDummyLines As Boolean) Dim Row As Long Dim i As Long Dim Column As Integer Application.ScreenUpdating = False qldws.Initialize ws Set myWS = ws Set wsM = New WsMacros Set wsAbs = New wsAbstract wsAbs.Initialize ws '---------------------------------------------------------- ' Open Quickload file '---------------------------------------------------------- If Append Then Open qlFile For Append As #1 Else Open qlFile For Output As #1 End If On Error GoTo ExportError Print #1, "!-----------------------------------------------------------------------" Print #1, "! Quickload file : " & qlFile Print #1, "! From workbook : " & ActiveWorkbook.FullName Print #1, "! Sheet : " & ActiveSheet.Name Print #1, "! Generated : " & FormatDateTime(Now, vbLongDate) & " " & _ FormatDateTime(Now, vbLongTime) Print #1, "! By : " & Environ("username") & "@" & Environ("computername") Print #1, "!-----------------------------------------------------------------------" Print #1, "" '---------------------------------------------------------- ' Write text "@FIELDS" '---------------------------------------------------------- Print #1, "@FIELDS" '---------------------------------------------------------- ' Check if key (NAME) field must bo composed from ' fields INSTALL, UNIT, TAG, SUB '---------------------------------------------------------- GetQuickloadFields SelectedColumnsOnly '---------------------------------------------------------- ' Write Recordset Fields '---------------------------------------------------------- Dim FirstColumnWritten As Boolean For i = 1 To colQldFields.count If Left$(colQldFields.Item(i), 1) <> "#" Then ' not a comment column If FirstColumnWritten = False Then FirstColumnWritten = True Else Print #1, ", "; End If PrintHeaderMacro colQldFields.Item(i), qldws.RowDataHeader End If Next i '---------------------------------------------------------- ' Write text "@<dataset name>" '---------------------------------------------------------- Print #1, "" Print #1, "@" & qldws.DatasetName '---------------------------------------------------------- ' Write all records ' (do not write rows that are hidden by the "Excel Autofilter" '---------------------------------------------------------- For Row = qldws.RowDataFirst To qldws.RowDataLast If Not SelectedRowsOnly Or wsAbs.RowSelected(Row) Then OneRow Row, SelectedColumnsOnly ElseIf WriteDummyLines Then Print #1, " " End If Next Row '---------------------------------------------------------- ' Close Quickload file '---------------------------------------------------------- Print #1, "" Close #1 Set qldws = Nothing Set wsM = Nothing Application.ScreenUpdating = True Set wsAbs = Nothing Exit Sub ExportError: Close #1 Application.ScreenUpdating = True Set wsM = Nothing Set qldws = Nothing Set wsAbs = Nothing ' propagate error Err.Raise Err.Number, Err.Source, Err.Description, Err.HelpFile, Err.HelpContext End Sub '---------------------------------------------------------- ' Write one row '---------------------------------------------------------- Private Sub OneRow(Row As Long, SelectedColumnsOnly As Boolean) Dim FirstColumnWritten As Boolean Dim Column As Integer Dim ws As Worksheet Set ws = qldws.Worksheet FirstColumnWritten = False '----------------------------------------- ' Write composed key field '----------------------------------------- If ComposedKey Then PrintFieldMacro "", qldws.getKeyValue(Row), Row FirstColumnWritten = True End If '----------------------------------------- ' Write composed key field '----------------------------------------- For Column = 1 To qldws.ColumnCount ' Debug.Print Column, ws.Cells(qldws.RowDataHeader, Column), ws.Cells(Row, Column), Row If Left$(ws.Cells(qldws.RowDataHeader, Column), 1) <> "#" Then ' not a comment column ' If Not SelectedColumnsOnly Or _ ' (SelectedColumnsOnly And _ ' Not Intersect(Selection, myWs.Cells(qldws.RowDataHeader, Column)) Is Nothing) Then If ColSelected(Column) Then If (Not ComposedKey Or ( _ ComposedKey And _ qldws.IsSplitNameField(ws.Cells(qldws.RowDataHeader, Column)) = False And _ UCase$(ws.Cells(qldws.RowDataHeader, Column)) <> "NAME")) Then If FirstColumnWritten = False Then FirstColumnWritten = True Else Print #1, ", "; End If PrintFieldMacro ws.Cells(qldws.RowDataHeader, Column), ws.Cells(Row, Column), Row End If End If End If Next Column Print #1, "" End Sub '---------------------------------------------------------- ' Evaluate Header macro '---------------------------------------------------------- Private Sub PrintHeaderMacro(ByVal CellContents As String, Row As Long) CellContents = Trim$(CellContents) If Left$(CellContents, 1) = "$" Then Dim i As Integer On Error GoTo HeaderMacroNotFound With wsM.HeaderMacro(CellContents) For i = 1 To .FieldCount Print #1, .Field(i); If i <> .FieldCount Then Print #1, ", "; End If Next i End With Else If CellContents = "<none>" Then CellContents = "" Print #1, CellContents; End If Exit Sub HeaderMacroNotFound: On Error GoTo ItemNameMacroNotFound Print #1, wsM.ItemNameMacro(CellContents).Field; Exit Sub ItemNameMacroNotFound: ' Throw error Err.Raise Err.Number, Err.Source, _ Err.Description & vbCrLf & vbCrLf & "Cannot evaluate macro" & CellContents, _ Err.HelpFile, Err.HelpContext End Sub '---------------------------------------------------------- ' Evaluate Field macro '---------------------------------------------------------- Private Sub PrintFieldMacro(HeaderMacroName As String, ByVal CellContents As String, Row As Long) CellContents = Trim$(CellContents) If Left$(CellContents, 1) = "$" Then Dim i As Integer On Error GoTo HeaderMacroNotFound With wsM.HeaderMacro(HeaderMacroName).FieldMacro(CellContents) For i = 1 To .FieldCount Print #1, """" & .Field(i) & """"; If i <> .FieldCount Then Print #1, ", "; End If Next i End With Else If CellContents = "<none>" Then CellContents = "" Print #1, """" & CellContents & """"; End If Exit Sub HeaderMacroNotFound: On Error GoTo ItemNameMacroNotFound Print #1, """" & CellContents & """"; Exit Sub ItemNameMacroNotFound: ' Throw error Err.Raise Err.Number, Err.Source, _ Err.Description & vbCrLf & vbCrLf & "Cannot evaluate macro" & CellContents, _ Err.HelpFile, Err.HelpContext End Sub '-------------------------------------------------------------------- ' Get quickload field names ' normally they correspond with the Excel header fields, exceptions are ' made for "composed keys" for UNIT_DF, ITEM_DEF, etc. ' ' Outputs: ComposedKey - indicates that key is composed ' colQldFields - collection of fields written to Quickload file ' '-------------------------------------------------------------------- Private Sub GetQuickloadFields(SelectedColumnsOnly As Boolean) Set colQldFields = New Collection ComposedKey = True ' assume True Dim col As Long '---------------------------------------------------------- ' Check if key (NAME) field must bo composed from ' fields INSTALL, UNIT, TAG, SUB '---------------------------------------------------------- ComposedKey = qldws.hasSplitName ColInstall = qldws.ColFieldName("INSTALL") ColUnit = qldws.ColFieldName("UNIT") ColTag = qldws.ColFieldName("TAG") ColSub = qldws.ColFieldName("SUB") ColGroupName = qldws.ColFieldName("GROUP_NAME") '---------------------------------------------------------- ' Fill Fields collection '---------------------------------------------------------- If ComposedKey Then colQldFields.Add "NAME" End If Dim FieldContents As String Dim R As Range For col = 1 To qldws.ColumnCount ' Find out about selected columns FieldContents = "" ColSelected(col) = True If SelectedColumnsOnly Then Set R = Intersect(Selection, myWS.Cells(qldws.RowDataHeader, col)) If R Is Nothing Then FieldContents = "#" ' fake commment column ColSelected(col) = False End If End If FieldContents = FieldContents & UCase$(qldws.Worksheet.Cells(qldws.RowDataHeader, col)) If ComposedKey Then If col <> ColInstall And _ col <> ColUnit And _ col <> ColTag And _ col <> ColSub And _ col <> ColGroupName Then colQldFields.Add FieldContents End If Else colQldFields.Add FieldContents End If Next col End Sub '--------------------------------------- ' Read Shift-JIS and Write UTF-8N '--------------------------------------- Public Sub WriteUTF8N(strFilename As String) Dim objReadStream As Object Dim objWriteStream As Object Dim bytData() As Byte Const adTypeText = 2 Const adTypeBinary = 1 Const adReadLine = -2 Const adWriteLine = 1 Const adCRLF = -1 Const adSaveCreateOverWrite = 2 Set objReadStream = CreateObject("ADODB.Stream") Set objWriteStream = CreateObject("ADODB.Stream") With objReadStream .Open .Type = adTypeText .Charset = "GB2312" .LineSeparator = adCRLF .LoadFromFile strFilename End With With objWriteStream .Open .Type = adTypeText .Charset = "UTF-8" .LineSeparator = adCRLF End With Do Until objReadStream.EOS objWriteStream.WriteText objReadStream.ReadText(adReadLine), adWriteLine Loop objReadStream.Close With objWriteStream .Position = 0 .Type = adTypeBinary .Position = 3 bytData = .Read .Close .Open .Position = 0 .Type = adTypeBinary .Write bytData .SaveToFile strFilename, adSaveCreateOverWrite ' .SaveToFile strFilename & ".txt", adSaveCreateOverWrite .Close End With End Sub 用VS编写C#程序

大家在看

recommend-type

HCIE-Storage实验手册06---Oracle主备容灾方案实验手册.docx

HCIE-Storage实验手册06---Oracle主备容灾方案实验手册.docx
recommend-type

通达信DLL插件编程示例(源码)

通达信DLL插件编程示例(源码)
recommend-type

C#调用LibVLCSharp库播放视频 句柄播放 或回调播放

C#调用LibVLCSharp包播放视频 1、句柄播放视频, media = new Media(libVLC, @textBox2.Text/*openDialog.FileName*/, FromType.FromPath); //赋值播放的句柄 mediaPlayer.Hwnd = this.panel1.Handle; mediaPlayer.Play(media); 2、回调函数播放视频 mediaPlayer.SetVideoFormat("RV32", _width, _height, _pitch); mediaPlayer.SetVideoCallbacks(VideoLockCallBack, null/*VideoUnlockCallBack*/, DisplayVideo); mediaPlayer.Play(media); play、pause、stop、TakeSnapshot等常规的函数调用 此项目功能简单,只做启蒙用
recommend-type

思科7960/7940 sip 8.6 固件

Cisco Call Manager 系统从7.1 升级的9.1, 部分电话7941和7942的firmware没有成功从8-3-1s升级到9-3-1SR1。 虽然这样的电话也能工作,但有时会自动重启。没升级成功的主要原因是8-3-1S必须经过一个中间版本8-5-2S才能升级到9-3-1SR1。没升级成功的电话分别在5个站点,Call Manager 在其中一个站点。跨WAN升级很慢。因此想找个本地服务器的方法。
recommend-type

aspweb,免费IIS模拟器,支持ASP

aspweb.exe是一款功能强大的IIS模拟器,支持ASP。使用时将aspweb.exe放在网站的根目录,双击打开就可运行测试该网站程序。对于未安装IIS的XP用户,非常简单实用! IIS强大模拟软件 ASP 必用

最新推荐

recommend-type

Leach算法分析从wireless.tcl文件中分析leach的具体流程

LEACH (Low-Energy Adaptive Clustering Hierarchy) 算法是一种在无线传感器网络中用于节能的自组织聚类协议。在分析LEACH的具体流程时,我们主要关注其在`wireless.tcl`文件中的实现。 首先,`wireless.tcl`文件...
recommend-type

opencv4.5.5 基于微信在opencv开源的二维码扫码 opencv-wechat-qrcode.zip

opencv4.5.5 基于微信在opencv开源的二维码扫码 opencv-wechat-qrcode.zip
recommend-type

Kotlin 二维码_条形码.zip

Kotlin 二维码_条形码.zip
recommend-type

Matlab_无人潜水器动力学仿真模型_Matlab_Simulink model of UUV dynamics.zi

Matlab_无人潜水器动力学仿真模型_Matlab_Simulink model of UUV dynamics.zip
recommend-type

Hyperledger Fabric v2与Accord Project Cicero智能合约开发指南

标题和描述中提到的“hlf-cicero-contract:Accord Project Cicero与Hyperledger Fabric v2签约”以及“半西约合同”暗示了与智能合约和区块链技术相关的知识点。下面详细说明这些知识点: ### 智能合约与区块链技术 智能合约是一套运行在区块链上的程序,当合约条款被触发时,合约会自动执行相应的操作。这种自动执行的特点使得智能合约特别适合于执行多方之间的可信交易,它能减少或消除中介服务的需要,从而降低交易成本并提高效率。 区块链技术是一种分布式账本技术,通过加密算法和共识机制保证了交易数据的不可篡改性和透明性。区块链上的每一笔交易都会被网络中的多个节点验证并记录,确保了交易记录的安全性。 ### Hyperledger Fabric v2 Hyperledger Fabric 是由Linux基金会托管的一个开源项目,它是企业级区块链框架,旨在为商业应用提供安全、模块化、可扩展的区块链平台。Hyperledger Fabric v2.2是该框架的一个版本。 Hyperledger Fabric v2支持链码(Chaincode)概念,链码是部署在Hyperledger Fabric网络上的应用程序,它可以被用来实现各种智能合约逻辑。链码在运行时与网络中的背书节点和排序服务交互,负责验证、执行交易以及维护账本状态。 ### Accord Project Cicero Accord Project Cicero 是一个开源的智能合同模板和执行引擎,它允许开发者使用自然语言来定义合同条款,并将这些合同转换为可以在区块链上执行的智能合约。CiceroMark是基于Markdown格式的一种扩展,它允许在文档中嵌入智能合约逻辑。 通过Accord Project Cicero,可以创建出易于理解、可执行的智能合约。这些合同可以与Hyperledger Fabric集成,利用其提供的安全、透明的区块链网络环境,从而使得合同条款的执行更加可靠。 ### 智能合约的安装与部署 描述中提到了“安装”和“启动”的步骤,这意味着为了使用HLF v2.2和Accord Project Cicero,需要先进行一系列的配置和安装工作。这通常包括设置环境变量(例如HLF_INSTALL_DIR)、安装区块链网络(Test-Net)以及安装其他必需的软件工具(如jq)。 jq是一个轻量级且灵活的命令行JSON处理器,常用于处理JSON数据。在区块链项目中,jq可以帮助开发者处理链码或智能合约的数据,特别是在与网络节点交互时。 ### JavaScript 标签 标签“JavaScript”表明本项目或相关文档中会涉及到JavaScript编程语言。Hyperledger Fabric v2支持多种智能合约语言,其中JavaScript是一个广泛使用的选项。JavaScript在编写链码时提供了灵活的语法和强大的库支持,是进行区块链开发的一个流行选择。 ### 文件结构 文件名称列表“hlf-cicero-contract-master”暗示这是一个包含所有相关文件和资源的项目源代码目录。这个名称通常表明开发者可以从该目录开始探索、安装和配置项目的所有组件。 ### 综合知识点 1. 智能合约与区块链技术可以自动化执行多方面可信交易,降低交易成本并提高效率。 2. Hyperledger Fabric v2为企业提供一个安全、模块化、可扩展的区块链平台。 3. Accord Project Cicero结合Markdown格式的CiceroMark,将自然语言定义的合同条款转换为可执行的智能合约。 4. 智能合约的安装和部署涉及到一系列配置步骤,包括设置环境变量、安装必要的软件工具等。 5. JavaScript是编写智能合约的流行语言之一,为区块链开发提供灵活性和强大的库支持。 6. 项目文件结构表明从一个主目录可以探索和配置所有项目相关文件和资源。 以上是根据文件标题、描述、标签以及文件名称列表所提取的相关知识点。这些知识点对于理解Hyperledger Fabric v2和Accord Project Cicero在智能合约中的应用尤为重要。
recommend-type

深度神经网络优化技巧全解析

# 深度神经网络优化技巧全解析 ## 1 超越 Sigmoid 函数 在神经网络中,Sigmoid 函数曾被广泛使用,但它存在一些问题,如梯度消失。研究人员一直在寻找更好的激活函数,且不同的激活函数在不同场景下表现各异。 ### 1.1 ReLU 函数登场 如今,修正线性单元(ReLU)成为了 Sigmoid 的常用替代函数。与 Sigmoid 相比,ReLU 非常简单,以下是其 Python 实现: ```python def relu(z): if z <= 0: return 0 else: return z ``` ReLU 由两段直
recommend-type

什么是噪声功率密度

<think> 嗯,用户这次问的是噪声功率密度的定义,结合之前的系统指令和站内引用,需要给出清晰准确的中文解释。用户可能是电子工程或通信专业的学生,正在学习噪声相关的理论基础,也可能是工程师需要实际应用概念。从引用来[^1]看,用户对相位噪声的定义有基础认知,但需要系统梳理核心概念。 噪声功率密度最本质的定义应该是单位带宽内的噪声功率。引用[^2]提到电阻热噪声的例子很典型,50Ω电阻在300K环境下功率谱密度是定值(0.9nV/√Hz)²,这说明: 1. 它描述的是噪声功率随频率分布的密度 2. 与带宽强相关(带宽加倍则总功率加倍) 3. 单位通常用W/Hz或V²/Hz 维纳-辛钦定理(
recommend-type

Libshare: Salesforce的高效可重用模块集合

Salesforce是一个云基础的CRM平台,它允许用户构建定制应用程序来满足特定的业务需求。Apex是Salesforce平台上的一个强类型编程语言,用于开发复杂的业务逻辑,通过触发器、类和组件等实现。这些组件使得开发者可以更高效地构建应用程序和扩展Salesforce的功能。 在提到的"libshare:经过测试的Salesforce可重用模块"文件中,首先介绍了一个名为Libshare的工具包。这个工具包包含了一系列已经过测试的可重用模块,旨在简化和加速Salesforce应用程序的开发。 Libshare的各个组成部分的知识点如下: 1. 设置模块:在Salesforce应用程序中,应用程序设置的管理是必不可少的一部分。设置模块提供了一种简便的方式存储应用程序的设置,并提供了一个易用的API来与之交互。这样,开发者可以轻松地为不同的环境配置相同的设置,并且可以快速地访问和修改这些配置。 2. Fluent断言模块:断言是单元测试中的关键组成部分,它们用于验证代码在特定条件下是否表现预期。Fluent断言模块受到Java世界中Assertj的启发,提供了一种更流畅的方式来编写断言。通过这种断言方式,可以编写更易于阅读和维护的测试代码,提高开发效率和测试质量。 3. 秒表模块:在性能调优和效率测试中,记录方法的执行时间是常见的需求。秒表模块为开发者提供了一种方便的方式来记录总时间,并跟踪每种方法所花费的时间。这使得开发者能够识别瓶颈并优化代码性能。 4. JsonMapper模块:随着Web API的广泛应用,JSON数据格式在应用程序开发中扮演了重要角色。JsonMapper模块为开发者提供了一个更高级别的抽象,用于读取和创建JSON内容。这能够大幅简化与JSON数据交互的代码,并提高开发效率。 5. utils模块:在软件开发过程中,经常会遇到需要重复实现一些功能的情况,这些功能可能是通用的,例如日期处理、字符串操作等。utils模块提供了一系列已经编写好的实用工具函数,可以用于节省时间,避免重复劳动,提高开发效率。 6. 记录器模块:记录器通常用于记录应用程序的运行日志,以便于问题诊断和性能监控。系统提供的System.debug功能虽然强大,但在大型应用中,统一的记录器包装器可以使得日志管理更加高效。记录器模块支持记录器名称,并且可以对日志进行适当的封装。 7. App Logger模块:App Logger模块扩展了记录器模块的功能,它允许开发者将日志语句保存到一个精心设计的App Log对象中。此外,App Logger模块支持存储长达56k字符的日志内容,这对于复杂应用的监控和调试非常有用。 8. 应用程序任务模块:在处理异步作业时,例如批量数据处理或定时任务,需要有一个框架来管理和跟踪这些任务。应用程序任务模块提供了一个框架,用于处理可排队的作业,并能够跟踪这些任务的执行情况。 通过Libshare提供的这些模块,Salesforce的开发者能够减少开发工作量,加快开发速度,并提高代码质量。这些模块能够帮助开发者避免重复的“造轮子”工作,专注于核心业务逻辑的实现。同时,由于Libshare作为托管程序包发布,开发者无需担心代码的维护和管理,只需将其添加到自己的Salesforce组织中即可使用。 Libshare的发布也强调了可重用性的重要性,这是软件工程领域中长期提倡的一个原则。通过使用可重用的组件,开发者能够遵循DRY(Don't Repeat Yourself)原则,从而减少代码的冗余,提高生产效率,同时降低因重复编写相同代码而导致错误的风险。 总之,Libshare是一个有价值的资源,对于那些希望在Salesforce平台上快速构建高效、可靠应用程序的开发者来说,这些预置的、经过测试的模块无疑是一个强大的助手。
recommend-type

机器学习技术要点与应用解析

# 机器学习技术要点与应用解析 ## 1. 机器学习基础概念 ### 1.1 数据类型与表示 在编程中,数据类型起着关键作用。Python 具有动态类型特性,允许变量在运行时改变类型。常见的数据类型转换函数包括 `bool()`、`int()`、`str()` 等。例如,`bool()` 函数可将值转换为布尔类型,`int()` 用于将值转换为整数类型。数据类型还包括列表(`lists`)、字典(`dictionaries`)、元组(`tuples`)等集合类型,其中列表使用方括号 `[]` 表示,字典使用花括号 `{}` 表示,元组使用圆括号 `()` 表示。 ### 1.2 变量与命名
recommend-type

点击歌曲没反应

<think> 我们之前已经讨论了如何将音频文件显示在QListView中,并希望实现点击播放。现在遇到的问题是点击列表项没有反应。 原因分析: 1. 我们没有将点击信号连接到播放槽函数。 2. 播放列表(QMediaPlaylist)可能没有正确添加媒体。 3. 媒体路径可能不正确。 解决方案: 按照之前的思路,我们需要做以下几步: 步骤1:确保已经创建了QMediaPlayer和QMediaPlaylist对象,并且播放器设置了播放列表。 步骤2:将QListView的点击信号(clicked)连接到自定义的槽函数,在该槽函数中设置播放列表的当前索引并播放。 步骤3: